<?php
/**
 * 策略模式,完成计算器
 * 策略和工厂的区别:
 *  工厂:在new子类是全局的,直接拿这个子类调用各个方法
 *  策略:不直接去触碰new 过来的子类,而是当作虚拟类的一个属性,再经过属性去调用子类的方法
 * 这样在客户端调用的时候,就不要使用if语句等判断级别
 *
 */

interface Math{
    public function calc($op1, $op2);
}


class MathAdd implements Math{
    public function calc($op1, $op2){
        return $op1 + $op2;
    }
}

class MathSub implements Math{
    public function calc($op1, $op2){
        return $op1 - $op2;
    }
}


class MathMul implements Math{
    public function calc($op1, $op2){
        return $op1 * $op2;
    }
}

class MathDiv implements Math{
    public function calc($op1, $op2){
        return $op1 / $op2;
    }
}


/*
    一般思路根据传过来的参数判断+- * / 来调用每个类
 */

/**
 * 封装一个虚拟计算器
 *
 */
class CMath{
    /**
     * 真是计算器
     * @var unknown
     */
    protected $calc = null;

    public function __construct($type){
        $calc = 'Math'.$type;
        $this->calc = new $calc();
    }

    public function calc($op1, $op2){
       return $this->calc->calc($op1, $op2);

    }
}

$type = 'Sub';
$cmath = new CMath($type);
echo $cmath->calc(10, 5);