抽象工厂模式为一个产品族提供了统一的创建接口。当需要这个产品族的某一系列的时候,可以为此系列的产品族创建一个具体的工厂类。
Abstract.png

什么是产品族?图上展示的是 Wechat产品下的预约、待办、联系人。它们之间虽然没有任何关系,但它们都实现了同一个 encoder()方法,而且它们在功能上是相似的。
而抽象接口 CommonsManager类定义了用于生成三种产品的接口。WechatCommonsManager则是具体产品的创建者。

  1. interface CommonsManager
  2. {
  3. public function getApptEncoder(): ApptEncoder;
  4. public function getTtdEncoder(): TtdEncoder;
  5. public function getContactEncoder(): ContactEncoder;
  6. }
  1. // 预约
  2. abstract ApptEncoder
  3. {
  4. public function encoder(): string;
  5. }
  6. // 待办
  7. abstract TtdEncoder
  8. {
  9. public function encoder(): string;
  10. }
  11. // 联系人
  12. abstract ContactEncoder
  13. {
  14. public function encoder(): string;
  15. }
  1. class WechatApptEncoder extends ApptEncoder
  2. {
  3. public function encoder(): string
  4. {
  5. return 'This is Wechat ApptEncoder';
  6. }
  7. }
  8. class WechatTtdEncoder extends ApptEncoder
  9. {
  10. public function encoder(): string
  11. {
  12. return 'This is Wechat TtdEncoder';
  13. }
  14. }
  15. class WechatContactEncoder extends ApptEncoder
  16. {
  17. public function encoder(): string
  18. {
  19. return 'This is Wechat ContactEncoder';
  20. }
  21. }
  1. class WechatCommonsManager implements
  2. {
  3. public function getApptEncoder(): ApptEncoder
  4. {
  5. return new WechatApptEncoder();
  6. }
  7. public function getTtdEncoder(): ApptEncoder
  8. {
  9. return new WechatTtdEncoder();
  10. }
  11. public function getContactEncoder(): ApptEncoder
  12. {
  13. return new WechatContactEncoder();
  14. }
  15. }
  1. class Client
  2. {
  3. public static function main()
  4. {
  5. self::run(WechatCommonsManager);
  6. }
  7. public static function run(CommonsManager $manager)
  8. {
  9. echo $manager->getApptEncoder()->encoder();
  10. echo $manager->getTtEncoder()->encoder();
  11. echo $manager->getContactEncoder()->encoder();
  12. }
  13. }
  14. // 运行
  15. Client::main();

特点:

  • 解除了系统与实现细节之间的耦合
  • 增加或替换产品族变得容易
  • 保证了一致性: WechatCommonsManager 可以确保只使用 WechatClass 格式的类

    缺点:

  • 添加新产品会非常的痛苦

    使用场景:

  • 当有多个产品时,而系统只消费某一产品,就如本例的 wechat 系列产品

  • 同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计时体现出来
  • 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现