概念:抽象模式(Abstact Factory)是一种常见的软件设计模式,为产品族提供了统一的创建接口,当需要产品族的某一系列时,可以具体为这一系列生成具体的工厂类。
一、抽象工厂模式意图
抽象工厂模式提供创建一个与系统相关或相互依赖对象的接口,不需要指定他们的类。
二、抽象工厂模式图
三、抽象工厂模式中的主要角色
抽象工厂(Abstract Factory)角色:声明创建一个抽象对象产品的接口,通常以接口或抽象类实现;所有具体工厂类都必须实现或者继承这个类。
具体工厂(Concrete Factory)角色:实现创建产品对象的实现。客户端直接调用创建的这个产品对象的实例,该角色包含了选择合适的产品对象的逻辑,通常使用具体类实现。
抽象产品(Abstract Product)角色:声明一类产品的接口,它既是工厂模式创建对象的父类也是它们共同拥有的接口。
具体产品(Concrete Product)角色:实现抽象产品角色定义的接口,定义一个将被对应的具体工厂所创建的产品对象,内部包含了应用程序的业务逻辑。
四、抽象工厂模式的优缺点
优点:
- 分离了具体的类;
- 是增加或者替换产品族变得更加方便;
- 利于产品的一致性;
缺点:
难以支持新种类的产品,因为AbstractFactory接口确定了可以被创建的产品合集。所以支持新各类的产品就需要扩展工厂接口,从而导致AbstractFactory类以及其所有子类的改变。
记:
抽象工厂是已一种倾斜的方式支持新增的产品,为新产品族的增加提供便利,而不能为新的产品室等级结构提供便利。
五、抽象工厂模式的适用场景
- 系统不应依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的;
- 系统的产品有多于一个产品族,而系统只消费其中某一族的产品;
- 属于同一产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。
- 系统提供一个产品类的库,所有产品以同样的接口出现,从而使客户端不依赖于现实;
六、抽象工厂模式与其他模式
单例模式(singleton模式):具体工厂类可以设计成单例类,由于工厂通常有一个就可以,因此具体工厂类一般实现为一个Singleton。
工厂方法模式(factory method模式):抽象工厂创建产品的方法定义为工厂方法。
原型模式(prototype模式): 如果有多个可能的产品系列,具体的工厂也可以使用原型模式,具体工厂使用产品系列中每一个产品的原型进行实例化并且通过复制它的原型来创建新的产品。
七、抽象工厂模式代码示例
1 <?php 2 /** 3 * 抽象产品A 4 */ 5 interface AbstractProductA 6 { 7 /* 取得产品名 */ 8 public function getName(); 9 } 10 /** 11 * 抽象产品B 12 */ 13 interface AbstractProductB 14 { 15 /* 取得产品名 */ 16 public function getName(); 17 } 18 19 /** 20 * 具体产品A 21 */ 22 class ProductA implements AbstractProductA 23 { 24 private $_name; 25 26 public function __construct() 27 { 28 $this->_name = 'product A'; 29 } 30 31 public function getName() 32 { 33 return $this->_name; 34 } 35 } 36 37 /** 38 * 具体产品B 39 */ 40 class ProductB implements AbstractProductB 41 { 42 private $_name; 43 44 public function getName() 45 { 46 $this->_name = 'product B'; 47 } 48 } 49 50 /** 51 * 抽象工厂 52 */ 53 interface AbstactFactory 54 { 55 /* 创建等级结构为A的产品工厂方法 */ 56 public function CreateProductA(); 57 /* 创建等级结构为B的产品工厂方法 */ 58 public function CreateProductB(); 59 } 60 61 /** 62 * 具体工厂1 63 */ 64 class Factory1 implements AbstactFactory 65 { 66 public function CreateProductA() 67 { 68 return new ProductA; 69 } 70 71 public function CreateProductB() 72 { 73 return new ProductB; 74 } 75 } 76 77 /** 78 * 客户端 79 */ 80 81 class Client 82 { 83 /* 主要程序 */ 84 public static function main() 85 { 86 self::run(new Factory1()); 87 } 88 89 /** 90 * 调用工厂实际生成产品,输出产品名 91 * @param $factory AbstractFactory 工厂实例 92 */ 93 public static function run(AbstractFactory $factory) 94 { 95 $ProductA = $factory->CreateProductA(); 96 $ProductB = $factory->CreateProductB(); 97 echo $ProductA->getName().'<br/>'; 98 echo $ProductB->getName(),'<br/>'; 99 } 100 } 101 102 Client::main();
八、PHP中extends、implements、abstract、interface的区别
extends:
1、extends在类的声明中,通过它来继承一个类;
2、extends继承某个类,继承后可以使用父类的方法,也可以重写父类的方法;
3、extends继承父类,如果类被声明为final,则不能被继承。PHP和Java都不支持多重继承,c++可以;
4、extends可以实现父类,也可以调用父类初始化this.parent(),并且会覆盖父类定义的函数或者变量;
abstract:
用abstract修饰的类说明是一个抽象类,用abstract修饰的方法说明是一个抽象方法;抽象方法只能方法声明,不能方法实现内容。
抽象类不能实例化,通常将抽象方法作为子类方法重写使用,并且要把继承的抽象类里的方法全部实现。
implements:
1、一个类通过implements声明自己使用一个或者多个接口;
2、implements实现多个接口,接口的方法一般为空重写才可以使用;
3、extends不支持多重继承,继承只能继承一个类,但是可以用implements实现多个接口,用逗号分开;
4、implements实现父类,子类不可以覆盖父类定义的方法或变量,即使子类定义与父类相同的变量或者函数,也会被父类取代;
interface:
如果一个抽象类的所有方法都是抽象方法,且没有声明变量,并所有成员都是public权限,这种特殊的抽象类就是接口。并用关键字implements来实现接口的所有方法,并且必须全部完成。
cr:https://www.cnblogs.com/zxqblogrecord/p/9994550.html