工厂方法模式
- 父类提供一个创建对象的方法,允许子类决定实例化对象的类型。
- 静态方法是类与外界的接口, 返回的是一个对象。
简单工厂
先来看一个简单的,由浅入深。
<?php //Factory class Factory { public static function createProduct($type) { $product = null; switch ($type){ case 'A': $product = new ProductA(); break; case 'B': $product = new ProductB(); break; } return $product; } } //Product interface Product { public function show(); } class ProductA implements Product { public function show() { echo 'productA show'; } } class ProductB implements Product { public function show() { echo 'productB show'; } } //Client $productA = Factory::createProduct('A'); $productA->show();
简单直白点解释就是你向工厂提出你的需求,然后工厂按照你的需求交付你对应的产品。当然,这个产品实际上就是实例化的对象。然后你就可以调用对象里面封装的不同方法。
工厂模式
工厂模式在简单工厂的基础上又新建了分厂,这样可以把一些事情交给分厂去完成,不用自己来处理。将职能更加细化。
<?php //Factory abstract class Factory { //抽象工厂方法 abstract protected function FactoryMethod(); //操作方法 public function FactoryAction() { return $this->FactoryMethod(); } } //FactoryA class FactoryA extends Factory { //实现抽象方法 protected function FactoryMethod() { return new ProductA(); } //由于继承总厂,这里可以看做存在操作方法,写在这里是为例更方便理解。 public function FactoryAction() { return $this->FactoryMethod(); } } //Product interface Product { public function show(); } class ProductA implements Product { public function show() { echo 'productA show'; } } class ProductB implements Product { public function show() { echo 'productB show'; } } //Client $factoryA = new FactoryA(); $productA = $factoryA->FactoryAction(); $productA->show();
抽象工厂
抽象工厂对比工厂来说就更更更加灵活。如果说工厂只能生产宝马汽车的话,抽象工厂除了生产宝马汽车,还可以生产宝马汽车轮胎、方向盘、座椅等配件。本质就是在一个工厂类中通过不同的方法返回不同的对象。
<?php //Factory interface Factory { public function createProductA(); public function createProductB(); } //Factory1 实现商品A1和商品B1 class Factory1 implements Factory { public function createProductA1() { return new ProductA1(); } public function createProductB1() { return new ProductB1(); } } //Factory2 实现商品A2和商品B2 class Factory2 implements Factory { public function createProductA2() { return new ProductA2(); } public function createProductB2() { return new ProductB2(); } } //ProductA interface ProductA { public function show(); } class ProductA1 implements ProductA { public function show() { echo 'productA1 show'; } } class ProductA2 implements ProductA { public function show() { echo 'productA2 show'; } } //ProductB interface ProductB { public function show(); } class ProductB1 implements ProductB { public function show() { echo 'productB1 show'; } } class ProductB2 implements ProductB { public function show() { echo 'productB2 show'; } } //Client $factory1 = new Factory1(); $product1 = $factory1->createProductA1(); $product1->show();
- 使用场景
1、无法预知对象确切类别及其依赖关系时。工厂方法将创建产品的代码与实际使用产品的代码分离, 从而能在不影响其他代码的情况下扩展产品创建部分代码。
2、后期需要拓展你的逻辑功能。如 对接不同机构的SDK、不同平台的短信发送。
3、希望复用现有对象来节省系统资源, 而不是每次都重新创建对象。
- 优点
1、你可以避免创建者和具体产品之间的紧密耦合。
2、 单一职责原则。 你可以将产品创建代码放在程序的单一位置, 从而使得代码更容易维护。
3、开闭原则。 无需更改现有客户端代码, 你就可以在程序中引入新的产品类型。
- 缺点
应用工厂方法模式需要引入许多新的子类, 代码可能会因此变得更复杂。 最好的情况是将该模式引入创建者类的现有层次结构中。
好文章要分享:
https://zhuanlan.zhihu.com/p/100043909
https://zhuanlan.zhihu.com/p/101135549
https://zhuanlan.zhihu.com/p/101362847