【设计模式学习笔记】简单工厂模式、工厂模式、抽象工厂模式案例详解(C++实现)

简介: 【设计模式学习笔记】简单工厂模式、工厂模式、抽象工厂模式案例详解(C++实现)

一、简单工厂模式

1. 什么是简单工厂模式

Simple Factory Pattern,简单工厂模式,也叫做静态工厂方法模式(Static Factory Method Pattern)。属于类的创建型设计模式的一种,通过一个专门的类(工厂)来负责创建其他类的实例(具体产品),这些类都有一个共同的抽象类作为基类(抽象产品)。

简单工厂模式中的三个角色

  1. 工厂角色:Creator,用于创建所有的具体产品实例,是简单工厂模式的核心。工厂类直接被外部调用,并提供一个静态方法,根据传入的参数不同来创建不同产品类的实例。
  2. 抽象产品角色:Product,它是工厂类所创建的所有实例的类的共同基类,用于描述产品的公共接口。它和工厂类是依赖的关系(作为工厂类静态方法的返回值)。
  3. 具体产品角色:Concrete Product,它是抽象产品类的子类,也是工厂类要创建的目标类。

2. 简单工厂模式实例

假设我们要生产一个手机,由苹果手机,小米手机,首先我们应该定义一个抽象产品类PhoneInterface

1. //抽象产品类
2. class PhoneInterface
3. {
4. public:
5.  virtual void print_brand() = 0;
6. };

然后根据抽象产品类来实现具体的产品类,假设我们有苹果手机和小米手机

1. //具体产品类
2. class apple : public PhoneInterface
3. {
4. public:
5.  virtual void print_brand()
6.  {
7.    cout << "苹果手机" << endl;
8.  }
9. };
10. 
11. 
12. class XiaoMi : public PhoneInterface
13. {
14. public:
15.   virtual void print_brand()
16.   {
17.     cout << "小米手机" << endl;
18.   }
19. };

接下来就应该创建一个工厂类,在工厂类中定义了创建所有产品类实例的逻辑,以及选择创建哪个产品类实例的判断。

1. //工厂类
2. class Factory
3. {
4. public:
5.  PhoneInterface* production_phone(int flag)
6.  {
7.    PhoneInterface* pTemp = NULL;
8.    switch (flag) //所有的生产都集中在一个工厂中,每次修改都要在类中修改,不符合开闭原则
9.    {
10.     case 1:
11.       pTemp = new apple;
12.       break;
13.     case 2:
14.       pTemp = new XiaoMi;
15.       break;
16.     default:
17.       pTemp = NULL;
18.       break;
19.     }
20.     return pTemp;
21.   }
22. };

这样,客户就可以通过工厂类来生产客户所需要的手机,并可以成功完成手机型号的生产。

1. int main()
2. {
3.  Factory* pF = NULL;
4.  PhoneInterface* pPhone = NULL;
5. 
6.  pF = new Factory;
7.  pPhone = pF->production_phone(1);
8.  pPhone->print_brand();
9.  delete pPhone;
10. 
11.   pPhone = pF->production_phone(2);
12.   pPhone->print_brand();
13.   delete pF;
14.   delete pPhone;
15. 
16.   system("pause");
17.   return 0;
18. }

3. 简单工厂模式的优缺点

优点:工厂类是整个简单工厂模式的核心,通过工厂类对外隐藏了创建实例的具体细节,用户直接使用工厂类去创建自己需要的实例,而不必关心实例是如何创建出来的,也不必关心内部结构是怎么组织的。

缺点:正所谓成也萧何,败也萧何,简单工厂模式的优点来源于工厂类,其缺点也来源于工厂类,因为所有实例的创建逻辑都集中在工厂类中,一旦工厂出现问题,所有实例的创建都将无法进行,并且增删产品都要去修改工厂类来实现,不符合开闭原则。因为简单工厂模式不符合开闭原则,所以它不是标准的设计模式。

二、工厂模式

1. 什么是工厂模式

factory pattern,工厂模式同样属于类的创建型模式,也成为多态工厂模式。工厂模式对简单工厂模式不遵守开闭原则这一缺点做了修正,工厂模式多出了一个抽象工厂角色作为接口,实际的生产工作在具体工厂类中实现,这样进一步的抽象化使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。简单来说,就是把简单工厂中的工厂细分为不同产品的工厂,每个工厂生产一种产品。

  1. 抽象工厂角色(Creator),所有具体工厂都要实现这个接口;
  2. 具体工厂(Concrete Creator),负责实例化具体产品对象;
  3. 抽象角色(Product),和简单工厂模式一样,它是工厂类所创建的所有实例的类的共同基类,用于描述产品的公共接口。
  4. 具体产品角色(Concrete Product),具体工厂类所要实例化的对象。

2. 工厂模式实例

抽象产品类和具体产品类不变

1. //抽象产品类
2. class PhoneInterface
3. {
4. public:
5.  virtual void print_brand() = 0;
6. };
7. 
8. //苹果手机产品实现
9. class apple : public PhoneInterface
10. {
11. public:
12.   virtual void print_brand()
13.   {
14.     cout << "苹果手机" << endl;
15.   }
16. };
17. 
18. //小米手机产品实现
19. class XiaoMi : public PhoneInterface
20. {
21. public:
22.   virtual void print_brand()
23.   {
24.     cout << "小米手机" << endl;
25.   }
26. };

首先定义一个抽象的工厂类,来定义具体工厂的统一接口

1. //抽象工厂类
2. class FactoryInterface
3. {
4. public:
5.  virtual PhoneInterface* production_phone() = 0;
6. };

然后定义一个苹果手机工厂,用于生产苹果手机,再定义一个小米手机工厂,用于生产苹果手机,那么这两个工厂就是具体工厂角色

1. //苹果手机工厂
2. class AppleFactory : public FactoryInterface
3. {
4. public:
5.  virtual PhoneInterface* production_phone()
6.  {
7.    return new apple;
8.  }
9. };
10. 
11. //小米手机工厂
12. class XiaomiFactory : public FactoryInterface
13. {
14. public:
15.   virtual PhoneInterface* production_phone()
16.   {
17.     return new XiaoMi;
18.   }
19. };

当我们需要生产手机产品的时候,直接使用苹果手机工厂去创建苹果手机对象,用小米手机工厂去创建小米手机对象即可。假如,我们增加需求,需要华为手机,这时只要增加一个华为工厂和华为手机的实现类即可,工厂的抽象类和手机的抽象类都不用动,符合开闭原则。

1. int main()
2. {
3.  FactoryInterface* pFactory = NULL;
4.  PhoneInterface* pPhone = NULL;
5. 
6.  //要生产一台苹果手机
7.  //先创建一个苹果手机工厂
8.  pFactory = new AppleFactory;
9.  pPhone = pFactory->production_phone();
10.   pPhone->print_brand();
11.   delete pPhone;
12.   delete pFactory;
13. 
14.   //生产一个小米手机
15.   pFactory = new XiaomiFactory;
16.   pPhone = pFactory->production_phone();
17.   pPhone->print_brand();
18.   delete pPhone;
19.   delete pFactory;
20. 
21.   system("pause");
22.   return 0;
23. }

3. 简单工厂与工厂模式对比

简单工厂模式把所有的创建逻辑都放在了一个工厂类中,而工厂模式则是提供了一个抽象的工厂接口,由具体工厂去创建产品实例,极大的方便了增加产品,删除产品等操作,且很好的符合了开闭原则,简单工厂模式每次增删产品都要直接修改工厂类,而工厂模式只需要增加一个具体工厂类和一个具体产品类就可以完成功能的扩充。

在简单工厂模式中,客户端是面向具体工厂编程,增加产品要在工厂类中修改代码;而工厂模式是面向抽象工厂编程,增加产品只要创建一个新的具体工厂就可以了,这就是面向抽象类编程。

三、抽象工厂模式

1. 什么是抽象工厂模式

Abstract Factory Pattern,抽象工厂模式。假设在前面的工厂模式下,我们对产品线提出了进一步的要求,因为手机既要在国内销售,又要在国外销售,所以同一品牌手机增加了大陆版、美版、港版等产品线。如果使用工厂模式,每一个品牌的手机,每一个版本的手机都要单独一个具体工厂来创建,很不方便‘这时候,就有了抽象工厂模式,抽象工厂模式可以创建一个产品族(包含多条产品线)。抽象工厂模式用官方语言描述就是,一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。 她也有四种角色,和工厂模式一样。

  1. 抽象工厂角色(Creator),所有具体工厂都要实现这个接口,可以创建多个不同等级的产品(多条产品线);
  2. 具体工厂(Concrete Creator),负责实例化具体产品对象,多条产品线;
  3. 抽象角色(Product),和简单工厂模式一样,它是工厂类所创建的所有实例的类的共同基类,用于描述产品的公共接口。
  4. 具体产品角色(Concrete Product),具体工厂类所要实例化的对象。

2. 抽象工厂模式实例

首先创建一个抽象手机类

1. //抽象产品
2. class PhoneInterface
3. {
4. public:
5.  virtual void print_brand() = 0;
6. };

根据抽象手机类定义大陆版苹果手机类,美版苹果手机类,大陆版小米手机类,美版小米手机类

1. //美版的苹果手机
2. class UsApple : public PhoneInterface
3. {
4. public:
5.  virtual void print_brand()
6.  {
7.    cout << "美版的苹果手机" << endl;
8.  }
9. };
10. 
11. //大陆版小米手机
12. class ChinaXiaomi : public PhoneInterface
13. {
14. public:
15.   virtual void print_brand()
16.   {
17.     cout << "大陆版本的小米手机" << endl;
18.   }
19. };
20. 
21. //美版的小米手机
22. class UsXiaomi : public PhoneInterface
23. {
24. public:
25.   virtual void print_brand()
26.   {
27.     cout << "美版的小米手机" << endl;
28.   }
29. };

接下来定义一个抽象工厂类,该抽象工厂类中包含两个接口,一个是苹果手机生产线,一个是小米手机生产线

1. //抽象工厂
2. class FactoryInterface
3. {
4. public:
5.  //产品线1:苹果手机
6.  virtual PhoneInterface* production_apple() = 0;
7.  //产品线2:小米手机
8.  virtual PhoneInterface* production_xiaomi() = 0;
9. };

根据抽象工厂来定义两个具体工厂,一个是大陆版手机工厂,一个是美版手机工厂

1. //生产大陆版本手机的工厂
2. class ChinaFactory : public FactoryInterface
3. {
4. public:
5.  //产品线1:苹果手机
6.  virtual PhoneInterface* production_apple()
7.  {
8.    return new ChinaApple;
9.  }
10.   //产品线2:小米手机
11.   virtual PhoneInterface* production_xiaomi()
12.   {
13.     return new ChinaXiaomi;
14.   }
15. };
16. 
17. //生产美版手机的工厂
18. class UsFactory : public FactoryInterface
19. {
20. public:
21.   //产品线1:苹果手机
22.   virtual PhoneInterface* production_apple()
23.   {
24.     return new UsApple;
25.   }
26.   //产品线2:小米手机
27.   virtual PhoneInterface* production_xiaomi()
28.   {
29.     return new UsXiaomi;
30.   }
31. };

客户可以直接使用两个具体工厂去生产大陆版苹果/小米手机或美版苹果/小米手机

1. int main()
2. {
3.  FactoryInterface* pFactory = NULL;
4.  PhoneInterface* pPhone = NULL;
5. 
6.  //使用大陆版手机的工厂
7.  cout << "======大陆版手机工厂======" << endl;
8.  pFactory = new ChinaFactory;
9.  //生产大陆版苹果手机
10.   pPhone = pFactory->production_apple();
11.   pPhone->print_brand();
12.   delete pPhone;
13.   //生产大陆版小米手机
14.   pPhone = pFactory->production_xiaomi();
15.   pPhone->print_brand();
16.   delete pPhone;
17.   delete pFactory;
18. 
19.   //使用美版手机的工厂
20.   cout << "======美版手机工厂======" << endl;
21.   pFactory = new UsFactory;
22.   pPhone = pFactory->production_apple();
23.   pPhone->print_brand();
24.   delete pPhone;
25.   pPhone = pFactory->production_xiaomi();
26.   pPhone->print_brand();
27.   delete pPhone;
28.   delete pFactory;
29. 
30.   system("pause");
31.   return 0;
32. }

3. 抽象工厂类总结

当增加一个新的产品族时,只需要增加一个新的具体工厂即可,如果整个产品族只有一个等级的产品,比如只有一条生产线,抽象工厂就和工厂模式一样了。


相关文章
|
6月前
|
设计模式 算法 Java
设计模式觉醒系列(04)策略模式|简单工厂模式的升级版
本文介绍了简单工厂模式与策略模式的概念及其融合实践。简单工厂模式用于对象创建,通过隐藏实现细节简化代码;策略模式关注行为封装与切换,支持动态替换算法,增强灵活性。两者结合形成“策略工厂”,既简化对象创建又保持低耦合。文章通过支付案例演示了模式的应用,并强调实际开发中应根据需求选择合适的设计模式,避免生搬硬套。最后推荐了JVM调优、并发编程等技术专题,助力开发者提升技能。
|
9月前
|
设计模式 存储 缓存
「全网最细 + 实战源码案例」设计模式——享元模式
享元模式(Flyweight Pattern)是一种结构型设计模式,旨在减少大量相似对象的内存消耗。通过分离对象的内部状态(可共享、不变)和外部状态(依赖环境、变化),它有效减少了内存使用。适用于存在大量相似对象且需节省内存的场景。模式优点包括节省内存和提高性能,但会增加系统复杂性。实现时需将对象成员变量拆分为内在和外在状态,并通过工厂类管理享元对象。
291 92
|
9月前
|
设计模式 存储 算法
「全网最细 + 实战源码案例」设计模式——命令模式
命令模式(Command Pattern)是一种行为型设计模式,将请求封装成独立对象,从而解耦请求方与接收方。其核心结构包括:Command(命令接口)、ConcreteCommand(具体命令)、Receiver(接收者)和Invoker(调用者)。通过这种方式,命令的执行、撤销、排队等操作更易扩展和灵活。 适用场景: 1. 参数化对象以操作。 2. 操作放入队列或远程执行。 3. 实现回滚功能。 4. 解耦调用者与接收者。 优点: - 遵循单一职责和开闭原则。 - 支持命令组合和延迟执行。 - 可实现撤销、恢复功能。 缺点: - 增加复杂性和类数量。
271 14
「全网最细 + 实战源码案例」设计模式——命令模式
|
9月前
|
设计模式 存储 Java
「全网最细 + 实战源码案例」设计模式——责任链模式
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,允许将请求沿着处理者链进行发送。每个处理者可以处理请求或将其传递给下一个处理者,从而实现解耦和灵活性。其结构包括抽象处理者(Handler)、具体处理者(ConcreteHandler)和客户端(Client)。适用于不同方式处理不同种类请求、按顺序执行多个处理者、以及运行时改变处理者及其顺序的场景。典型应用包括日志处理、Java Web过滤器、权限认证等。
178 13
「全网最细 + 实战源码案例」设计模式——责任链模式
|
9月前
|
设计模式 算法 开发者
「全网最细 + 实战源码案例」设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,用于定义一系列可替换的算法或行为,并将它们封装成独立的类。通过上下文持有策略对象,在运行时动态切换算法,提高代码的可维护性和扩展性。适用于需要动态切换算法、避免条件语句、经常扩展算法或保持算法独立性的场景。优点包括符合开闭原则、运行时切换算法、解耦上下文与策略实现、减少条件判断;缺点是增加类数量和策略切换成本。示例中通过定义抽象策略接口和具体策略类,结合上下文类实现动态算法选择。
262 8
「全网最细 + 实战源码案例」设计模式——策略模式
|
9月前
|
设计模式 SQL 算法
「全网最细 + 实战源码案例」设计模式——模板方法模式
模板方法模式是一种行为型设计模式,定义了算法的骨架并在父类中实现不变部分,将可变部分延迟到子类实现。通过这种方式,它避免了代码重复,提高了复用性和扩展性。具体步骤由抽象类定义,子类实现特定逻辑。适用于框架设计、工作流和相似算法结构的场景。优点包括代码复用和符合开闭原则,缺点是可能违反里氏替换原则且灵活性较低。
211 7
「全网最细 + 实战源码案例」设计模式——模板方法模式
|
10月前
|
设计模式
「全网最细 + 实战源码案例」设计模式——模式扩展(配置工厂)
该设计通过配置文件和反射机制动态选择具体工厂,减少硬编码依赖,提升系统灵活性和扩展性。配置文件解耦、反射创建对象,新增产品族无需修改客户端代码。示例中,`CoffeeFactory`类加载配置文件并使用反射生成咖啡对象,客户端调用时只需指定名称即可获取对应产品实例。
178 40
|
10月前
|
设计模式 Java 开发者
「全网最细 + 实战源码案例」设计模式——适配器模式
适配器模式(Adapter Pattern)是一种结构型设计模式,通过引入适配器类将一个类的接口转换为客户端期望的另一个接口,使原本因接口不兼容而无法协作的类能够协同工作。适配器模式分为类适配器和对象适配器两种,前者通过多重继承实现,后者通过组合方式实现,更常用。该模式适用于遗留系统改造、接口转换和第三方库集成等场景,能提高代码复用性和灵活性,但也可能增加代码复杂性和性能开销。
213 28
|
9月前
|
设计模式 存储 安全
「全网最细 + 实战源码案例」设计模式——组合模式
组合模式(Composite Pattern)是一种结构型设计模式,用于将对象组合成树形结构以表示“部分-整体”的层次结构。它允许客户端以一致的方式对待单个对象和对象集合,简化了复杂结构的处理。组合模式包含三个主要组件:抽象组件(Component)、叶子节点(Leaf)和组合节点(Composite)。通过这种模式,客户端可以统一处理简单元素和复杂元素,而无需关心其内部结构。适用于需要实现树状对象结构或希望以相同方式处理简单和复杂元素的场景。优点包括支持树形结构、透明性和遵循开闭原则;缺点是可能引入不必要的复杂性和过度抽象。
244 22
|
10月前
|
设计模式 缓存 Java
「全网最细 + 实战源码案例」设计模式——代理模式
代理模式(Proxy Pattern)是一种结构型设计模式,通过代理对象控制对目标对象的访问并添加额外功能。它分为静态代理和动态代理,后者包括JDK动态代理和CGLIB动态代理。JDK动态代理基于接口反射生成代理类,而CGLIB通过继承目标类生成子类。代理模式适用于延迟初始化、访问控制、远程服务、日志记录和缓存等场景,优点是职责分离、符合开闭原则和提高安全性,缺点是增加系统复杂性。
248 25

热门文章

最新文章