🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
###### 简单代码实现 ~~~ //工厂类 class Factor { // 生成对象方法 public static function createDB() { echo '我生产了一个DB实例'; return new DB; } } //数据类 class DB { public function __construct() { echo __CLASS__ . PHP_EOL; } } $db = Factor::createDB(); ~~~ ###### 实现一个运算器 ~~~ // 抽象运算类 abstract class Operation { abstract public function getVal($i, $j); // 抽象方法不能包含方法体 } // 加法类 class OperationAdd extends Operation { public function getVal($i, $j) { return $i + $j; } } // 减法类 class OperationSub extends Operation { public function getVal($i, $j) { return $i - $j; } } //计数器工厂 class CounterFactor { private static $operation; // 工厂生产特定类对象方法 public static function createOperation(string $operation) { switch ($operation) { case '+': self::$operation = new OperationAdd; break; case '-': self::$operation = new OperationSub; break; } return self::$operation; } } $counter = CounterFactor::createOperation('+'); echo $counter->getVal(1, 2); ~~~ > 缺点:若是再增加一个乘法运算,除了增加一个乘法运算类之外,还得去工厂生产方法里面添加对应的case代码,违反了开放-封闭原则。 ###### 解决方法(1):通过传入指定类名 ~~~ // 计算器工厂 class CounterFactor { // 工厂生产特定类对象方法 public static function createOperation(string $operation) { return new $operation; } } class OperationMul extends Operation { public function getVal($i, $j) { return $i * $j; } } $counter = CounterFactor::createOperation('OperationMul'); ~~~ ###### 解决方法(2):通过抽象工厂模式 这里顺带提一个问题:如果我系统还有个生产一个文本输入器工厂,那么那个工厂和这个计数器工厂又有什么关系呢。 > 抽象高于实现 其实我们完全可以抽象出一个抽象工厂,然后将对应的对象生产交给子工厂实现。代码如下: ~~~ // 抽象运算类 abstract class Operation { abstract public function getVal($i, $j); //抽象方法不能包含方法体 } // 加法类 class OperationAdd extends Operation { public function getVal($i, $j) { return $i + $j; } } // 乘法类 class OperationMul extends Operation { public function getVal($i, $j){ return $i * $j; } } // 抽象工厂类 abstract class Factor { abstract static function getInstance(); } // 加法器生产工厂 class AddFactor extends Factor { // 工厂生产特定类对象方法 public static function getInstance() { return new OperationAdd; } } // 减法器生产工厂 class MulFactor extends Factor { public static function getInstance() { return new OperationMul; } } // 文本输入器生产工厂 class TextFactor extends Factor { public static function getInstance() {} } $mul = MulFactor::getInstance(); echo $mul->getVal(1, 2); ~~~ 作者:MonkeyNote 链接:https://www.jianshu.com/p/5a212a4cf958 来源:简书 简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。