当前位置:   article > 正文

C++设计模式Learning:工厂方法_lesson learn 如何在工厂开展

lesson learn 如何在工厂开展

前言

我们知道,设计模式的终极目标是高内聚,低耦合,好的软件代码必然离不开好的设计。最近在学习设计模式这块的内容,参考的书籍是程杰的《大话设计模式》,这本书对于初学者来说比较友好,易上手,博客里的内容是参考本书以及网络资源整理的。

博客更新基本上是边学边写的过程,写这个专题一是为了作为自己的知识备忘,二是希望能给正在学习设计模式的童鞋一些参考,博客中内容有纰漏或错误之处,还请指出,谢谢。

基本定义

工厂方法模式,属于创建型模式。工厂方法模式定义了一个用于创建工厂对象的公共接口,让子类决定实例化哪一个类。这样使得类实例化(具体产品的创建)延迟到工厂子类中。

UML图

工厂方式模式包含以下几类角色:

AbstractFactory:抽象工厂角色(接口)。提供创建产品的接口(抽象方法)CreateProduct,由具体工厂角色实现。

ConcreteFactory:具体工厂角色。用于实现抽象工厂的抽象方法,完成具体产品的创建。

Product:抽象产品角色,是所有具体产品的父类,定义了产品的规范,主要特性和功能接口等。

ConcreteProduct:具体产品角色,实现抽象产品类中提供的接口,具体产品由具体工厂来创建。

工厂方法模式实例

场景:生活中有很多人都想学雷锋做好事,比如学生、志愿者、工人等。学雷锋做好事的内容主要包括扫地、买米、洗衣等。

这里可以抽象出一个雷锋制造工厂的概念,还可以抽象出一个雷锋类,行使雷锋做好事的内容,下面展开。

UML图

代码实现

1. 雷锋类:提供雷锋做好事行为的接口。

  1. //LeiFeng类
  2. class LeiFeng {
  3. public:
  4. virtual void Sweep(void) = 0;
  5. virtual void BuyRice(void) = 0;
  6. virtual void Wash(void) = 0;
  7. };

2. 学雷锋的大学生类:

  1. class Undergraduate : public LeiFeng {
  2. public:
  3. virtual void Sweep(void)
  4. {
  5. std::cout << "Undergraduate.Sweep!!" << std::endl;
  6. }
  7. virtual void BuyRice(void)
  8. {
  9. std::cout << "Undergraduate.BuyRice!!" << std::endl;
  10. }
  11. virtual void Wash(void)
  12. {
  13. std::cout << "Undergraduate.Wash!!" << std::endl;
  14. }
  15. };

3. 学雷锋的志愿者类:

  1. class Volunteer: public LeiFeng {
  2. public:
  3. virtual void Sweep(void)
  4. {
  5. std::cout << "Volunteer.Sweep!!" << std::endl;
  6. }
  7. virtual void BuyRice(void)
  8. {
  9. std::cout << "Volunteer.BuyRice!!" << std::endl;
  10. }
  11. virtual void Wash(void)
  12. {
  13. std::cout << "Volunteer.Wash!!" << std::endl;
  14. }
  15. };

4. 学雷锋的工人类:

  1. class Worker: public LeiFeng {
  2. public:
  3. virtual void Sweep(void)
  4. {
  5. std::cout << "Worker.Sweep!!" << std::endl;
  6. }
  7. virtual void BuyRice(void)
  8. {
  9. std::cout << "Worker.BuyRice!!" << std::endl;
  10. }
  11. virtual void Wash(void)
  12. {
  13. std::cout << "Worker.Wash!!" << std::endl;
  14. }
  15. };

5. 雷锋工厂

  1. class LeiFengFactory {
  2. public:
  3. virtual LeiFeng* CreateLeiFeng(void) = 0;
  4. };

6. 学雷锋的大学生工厂

  1. class UndergraduateFactory : public LeiFengFactory {
  2. public:
  3. LeiFeng* CreateLeiFeng(void)
  4. {
  5. return new Undergraduate();
  6. }
  7. };

7. 学雷锋的志愿者工厂

  1. class VolunteerFactory : public LeiFengFactory {
  2. public:
  3. LeiFeng* CreateLeiFeng(void)
  4. {
  5. return new Volunteer();
  6. }
  7. };

8. 学雷锋的工人工厂

  1. class WorkerFactory : public LeiFengFactory {
  2. public:
  3. LeiFeng* CreateLeiFeng(void)
  4. {
  5. return new Worker();
  6. }
  7. };

7. 客户端测试代码

  1. int main(int argc, char* argv[])
  2. {
  3. LeiFengFactory *LeiFengFac = new UndergraduateFactory();
  4. LeiFeng* one = LeiFengFac->CreateLeiFeng();
  5. one->Sweep();
  6. one->Wash();
  7. one->BuyRice();
  8. LeiFeng* two = LeiFengFac->CreateLeiFeng();
  9. two->Sweep();
  10. two->Wash();
  11. two->BuyRice();
  12. return 0;
  13. }

优缺点和使用场景

优点:

1.灵活性增强,添加新产品时,只需添加对应的工厂类,无需修改现有代码,符合开闭原则。

2. 用户无需知道产品的具体创建过程,只需知道产品工厂类名。

缺点:

1. 类数量可能较多。

2. 每增加新产品需要增加具体产品类和具体工厂类,增加系统复杂度。

使用场景:

对于某个产品,调用者清楚地知道应该使用哪个具体工厂服务,实例化具体工厂,生产出具体的产品。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/42500
推荐阅读
相关标签
  

闽ICP备14008679号