🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
工厂模式的作用: 避免直接实例化对象,如果我们在很多地方都要实例化此对象,但是某一天对象的名字需要更改时,所有实例化的地方都要修改,而有了工厂模式就只修改工厂模式代码里的类名就可以了 <b style="color:red">**简单工厂--静态工厂方法模式**</b> >[danger] 我们把被创建的对象称为“产品”,把创建产品的对象称为“工厂”。如果要创建的产品不多,只要一个工厂类就可以完成 > 它的缺点是增加新产品时会违背“开闭原则” ``` //抽象产品 interface Fruit { # 种植 public function plant(); # 收获 public function harvest(); } //具体产品实现 class Apple implements Fruit { # 种植 public function plant(){ echo "苹果种下啦"; } # 收获 public function harvest(){ echo "苹果收获啦"; } } class Banana implements Fruit { # 种植 public function plant(){ echo "香蕉种下啦"; } # 收获 public function harvest(){ echo "香蕉收获啦"; } } //简单工厂--静态工厂方法模式 class SimpleFactory { public static function getFruitByParam($type) { switch ($fruitName) { case 'apple': return new Apple(); break; case 'banana': return new Banana(); break; default: throw new Exception("Error no the fruit"); break; } } } // 如果不用工厂模式,则需要提前指定具体类 // $fruit= new Apple(); // echo $fruit->plant(); // $fruit= new Banana(); // echo $fruit->plant(); // 用工厂模式,则不需要知道对象由什么类产生,交给工厂去决定 $fruit = SimpleFactory::getFruitByParam('Apple'); echo $fruit ->plant(); $fruit = SimpleFactory::getFruitByParam('Banana'); echo $fruit ->plant(); ``` <b style="color:red">**工厂方法--多态性工厂模式②**</b> >[danger]**主要优点有:** >* 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程; >* 在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则; > >**其缺点是:** >* 每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。 ![](https://img.kancloud.cn/37/74/3774f86ccb714b82e76d9e6ddcc66d6b_810x394.png) ~~~ /** * 虚拟产品接口类 * 定义好需要实现的方法 */ interface Fruit{ # 种植 public function plant(); # 生长 public function grow(); # 收获 public function harvest(); # 吃 public function eat(); } /** * 定义具体产品类 苹果 * 首先,我们要实现所继承的接口所定义的方法 * 然后定义苹果所特有的属性,以及方法 */ class Apple implements Fruit{ # 苹果树有年龄 private $treeAge; # 苹果有颜色 private $color; # 种植 继承fruit接口 public function plant(){ echo "grape plant"; } # 生长 继承fruit接口 public function grow(){ echo "grape grow"; } # 收获 继承fruit接口 public function harvest(){ echo "grape harvest"; } # 吃 继承fruit接口 public function eat(){ echo "grape eat"; } # 取苹果树的年龄 public function getTreeAge(){ return $this->treeAge; } # 设置苹果树的年龄 public function setTreeAge($age){ $this->treeAge = $age; return trie; } } /** * 定义具体产品类 葡萄 * 首先,我们要实现所继承的接口所定义的方法 * 然后定义葡萄所特有的属性,以及方法 */ class Grape implements Fruit{ # 葡萄是否有籽 private $seedLess; # 种植 继承fruit接口 public function plant(){ echo "grape plant"; } # 生长 继承fruit接口 public function grow(){ echo "grape grow"; } # 收获 继承fruit接口 public function harvest(){ echo "grape harvest"; } # 吃 继承fruit接口 public function eat(){ echo "grape eat"; } # 获取葡萄有籽无籽 public function getSeedLess(){ return $this->seedLess; } # 设置葡萄有籽无籽 public function setTreeAge($age){ $this->treeAge = $age; return trie; } } # 农场主Farmer(工厂)类接口 用来获取实例化的水果 interface CommFactory { # 定义个静态工厂方法 public function getFruit(); } # 苹果农场(工厂) class AppleFarm implements CommFactory{ public function getFruit(){ return new Apple(); } } # 葡萄农场(工厂) class GrapeFarm implements CommFactory{ public function getFruit(){ return new Grape(); } } # 调用 $appleFarm = new AppleFarm(); $apple=$appleFarm->getFruit(); $apple->plant(); $grapeFarm = new GrapeFarm(); $grape=$grapeFarm->getFruit(); ~~~ <b style="color:red">**抽象工厂--工具箱模式(ToolKit):**</b> 使用抽象工厂模式一般要满足以下条件。 * 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。 * 系统一次只可能消费其中某一族产品,即同族的产品一起使用。 抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下。 * 可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。 * 当增加一个新的产品族时不需要修改原代码,满足开闭原则。 其缺点是:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。 ![](https://img.kancloud.cn/3a/9b/3a9b701a75e0ba7971e862d89a354b3f_662x635.png) ~~~ /** * 虚拟产品接口类 * 定义好需要实现的方法 */ interface Fruit{ # 种植 public function plant(); # 生长 public function grow(); # 收获 public function harvest(); # 吃 public function eat(); } /** * 定义具体产品类 苹果 * 首先,我们要实现所继承的接口所定义的方法 * 然后定义苹果所特有的属性,以及方法 */ class Apple implements Fruit{ # 苹果树有年龄 private $treeAge; # 苹果有颜色 private $color; # 种植 继承fruit接口 public function plant(){ echo "grape plant"; } # 生长 继承fruit接口 public function grow(){ echo "grape grow"; } # 收获 继承fruit接口 public function harvest(){ echo "grape harvest"; } # 吃 继承fruit接口 public function eat(){ echo "grape eat"; } # 取苹果树的年龄 public function getTreeAge(){ return $this->treeAge; } # 设置苹果树的年龄 public function setTreeAge($age){ $this->treeAge = $age; return trie; } } /** * 定义具体产品类 葡萄 * 首先,我们要实现所继承的接口所定义的方法 * 然后定义葡萄所特有的属性,以及方法 */ class Grape implements Fruit{ # 葡萄是否有籽 private $seedLess; # 种植 继承fruit接口 public function plant(){ echo "grape plant"; } # 生长 继承fruit接口 public function grow(){ echo "grape grow"; } # 收获 继承fruit接口 public function harvest(){ echo "grape harvest"; } # 吃 继承fruit接口 public function eat(){ echo "grape eat"; } # 获取葡萄有籽无籽 public function getSeedLess(){ return $this->seedLess; } # 设置葡萄有籽无籽 public function setTreeAge($age){ $this->treeAge = $age; return trie; } } #业务扩张 农场遍布不同区域 interface Area{ public function showArea(); } class SichuanArea implements Area{ public function showArea(){ echo "四川地区"; } } class GuizhouArea implements Area{ public function showArea(){ echo "贵州地区"; } } # 抽象农场主Farmer(工厂) interface AbstractFactory { # 定义个静态工厂方法 public function getFruit(); public function getArea(); } # 四川的苹果农场(工厂) class SichuanAppleFarm implements AbstractFactory { public function getFruit(){ return new Apple(); } public function getArea(){ return new SichuanArea(); } } # 四川的葡萄农场(工厂) class SichuanGrapeFarm implements AbstractFactory { public function getFruit(){ return new Grape(); } public function getArea(){ return new SichuanArea(); } } # 贵州的葡萄农场(工厂) class GuizhouGrapeFarm implements AbstractFactory { public function getFruit(){ return new Grape(); } public function getArea(){ return new GuizhouArea(); } } # 贵州的苹果农场(工厂) class GuizhouAppleFarm implements AbstractFactory { public function getFruit(){ return new Apple(); } public function getArea(){ return new GuizhouArea(); } } # 调用 $gaf=new GuizhouAppleFarm();//贵州葡萄园 $gaf->getArea()->showArea(); $gaf->getFruit()->plant(); $sgf= new SichuanGrapeFarm();//四川葡萄园 $sgf->getArea()->showArea(); $sgf->getFruit()->plant(); ~~~