需求:完成一個計算器,計算2個數的加減乘除等操作

class Cal
{
    public function countVal ($num1, $num2, $type)
    {
        switch ($type) {
            case '+' :
                // 驗證……
                $count = $num1 + $num2;
                break;
            case '-' :
                // 驗證……
                $count = $num1 - $num2;
                break;
             // …… 若有其他計算累計,繼續加case判斷。
        }
    }
}

 以上代碼會有些問題,若驗證的代碼很長,或計算類型很多,那countVal方法就會變得非常長,將難以閱讀及維護。

改進如下:

interface IMath
{
    function count($num1, $num2);
}
class Add implements IMath
{
    public function count($num1, $num2)
    {
        return $num1 + $num2;
    }
}
class Sub implements IMath
{
    public function count($num1, $num2)
    {
        return $num1 - $num2;
    }
}
class Cal
{
    // 這里就叫簡單工廠模式
    public static function getMath ($type)
    {
        switch ($type) {
            case '+' :
                return new Add();
                break;
            case '-':
                return new Sub();
                break;
             // ……
        }
    }
}
$math = Cal::getMath('+');
echo $math->count(10,

 

以上代碼比之前的改進在與,在getMath方法里,只負責new出相應的計算類,不需要管具體的驗證等操作,而且寫好的計算類今后是不需要改動的

 

不過,這種簡單工廠模式只適合計算類型很少的情形。 如果計算類型很多,比如取模、平方根、正弦、余弦等。 那他就不符合了。

首先他違背了開閉原則,新增了一個計算類型,Cal類就需要修改。其次,getMath方法將很長,難以閱讀。

如何解決,使用工廠模式。