需求:完成一个计算器,计算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方法将很长,难以阅读。
如何解决,使用工厂模式。