当前位置 : 主页 > 网络编程 > 其它编程 >

C++设计模式之工厂模式(创建型模式)

来源:互联网 收集:自由互联 发布时间:2023-07-02
学习软件设计向OO高手迈进设计模式(Designpattern)是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人 学习软件设计向OO高手迈进 设计模式(Des
学习软件设计向OO高手迈进设计模式(Designpattern)是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人

学习软件设计向OO高手迈进 设计模式(Design pattern)是软件开发人员在软件开发过程中面临的一般问题的解决方案。 这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。 是前辈大神们留下的软件设计的"招式"或是"套路"。

什么是工厂模式

对于工厂模式具体上可以分为三类

  • 简单工厂模式
  • 工厂方法模式
  • 抽象工厂模式
  • 简单工厂模式

    简单工厂模式是最简单的设计模式之一其实它并不属于GOF的23种设计模式但应用也十分频繁同时也是其余创建型模式的基础因此有必要先学习简单工厂模式。

    简单工厂基本实现流程

  • 设计一个抽象产品类它包含一些公共方法的声明
  • 从抽象产品类中派生出多个具体产品类具体产品类中实现具体产品生产的相关代码
  • 设计一个工厂类工厂类提供一个生产各种产品的方法该方法根据传入参数产品名称创建不同的具体产品类对象
  • 客户端只需调用工厂类的这个方法并传入具体产品参数即可得到一个具体产品对象
  • 定义

    定义一个简单工厂类它可以根据参数的不同返回不同类的实例被创建的实例通常都具有共同的父类

    简单工厂模式结构

    从简单工厂模式的定义可以看出在简单工厂模式中大体上有3个角色

  • 工厂角色Creator这是简单工厂模式的核心它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用创建所需的产品对象
  • 抽象产品角色AbstractProduct这是简单工厂模式所创建的所有对象的父类它负责描述所有实例所共有的公共接口。该类可以是接口也可以是抽象类
  • 具体产品角色ConcreteProduct抽象产品的派生类包含具体产品特有的实现方法是简单工厂模式的创建目标
  • UML类图

    其UML类图如下

    在这里插入图片描述

    Version 1.0

    下面我们使用手机生产来讲解该模式

    一、定义抽象产品类AbstractProduct

    Phone类手机类AbstractProduct

    class Phone {public:virtual void make(void) 0;};

    二、定义具体产品类

    MiPhone类小米手机类Product1

    class MiPhone : public Phone {public:MiPhone() {this->make();}virtual void make(void) {cout << "make xiaomi phone!" << endl;}};

    IPhone类苹果手机类Product2

    class IPhone : public Phone {public:IPhone() {this->make();} virtual void make(void) {cout << "make iphone!" << endl;}};

    三、定义工厂类和工厂方法

    SimpleFactory类手机生产工厂类Factory

    class SimpleFactory {public:static Phone* makePhone(const string "MiPhone") {return new MiPhone();} else if (phoneType "iPhone") {return new IPhone();} return nullptr;}};

    四、客户端

    int main(int argc, char** argv) {// make xiaomi phone!Phone* miPhone SimpleFactory::makePhone("MiPhone"); // make iphonePhone* iPhone SimpleFactory::makePhone("iPhone"); return 0;}

    执行结果

    make xiaomi phone!make iphone!

    Version 1.1

    扩展增加生产华为手机实现

    一、扩展具体产品类

    Huawei类华为手机类Product3

    class HuaweiPhone : public Phone {public:HuaweiPhone() {this->make();} virtual void make(void) {cout << "make huawei phone!" << endl;}};

    二、扩展工厂类方法

    SimpleFactory类手机生产工厂类Factory

    class SimpleFactory {public:static Phone* makePhone(const string "MiPhone") {return new MiPhone();} else if (phoneType "iPhone") {return new IPhone();} else if (phoneType "HuaweiPhone") {return new HuaweiPhone();}return nullptr;}};

    三、扩展客户端

    int main(int argc, char** argv) {// make xiaomi phone!Phone* miPhone SimpleFactory::makePhone("MiPhone");// make iphonePhone* iPhone SimpleFactory::makePhone("iPhone");// make huawei phonePhone* huaweiphone SimpleFactory::makePhone("HuaweiPhone");return 0;}

    执行结果

    make xiaomi phone!make iphone!make huawei phone!

    在简单工厂模式中工厂类是整个模式的关键所在。它包含了必要的判断逻辑能够根据外界给定的条件去判断应该创建哪个具体类的实例。用户在使用时可以直接根据工厂类去创建所需的实例而无需关心这些对象是如何组织并创建的从这一点上来说这有利于整个软件体系结构的优化。但是简单工厂模式的缺点也正体现在工厂类上由于工厂类中集中了所有实例的创建逻辑当我们增加了一个新的 具体类时需要同时修改工厂类多加一个if这违反了“开闭原则”。

    优点

  • 工厂类提供创建具体产品的方法并包含一定判断逻辑客户不必参与产品的创建过程。
  • 客户只需要知道对应产品的参数即可参数一般简单好记如数字、字符或者字符串等。
  • 缺点

  • 扩展性差实例中想增加一种手机产品除了新增一个手机产品类还需要修改工厂类方法。
  • 不同的产品需要不同额外参数的时候 不支持。
  • 适用场合

  • 在程序中需要创建的对象很多导致对象的new操作多且杂时需要使用简单工厂模式。
  • 由于对象的创建过程是我们不需要去关心的而我们注重的是对象的实际操作所以我们需要分离对象的创建和操作两部分如此方便后期的程序扩展和维护。
  • 工厂方法模式(Factory Method)

    定义

    定义一个用于创建对象的接口但是让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。

    简单工厂模式中每新增一个具体产品就需要修改工厂类内部的判断逻辑。为了不修改工厂类遵循开闭原则工厂方法模式中不再使用工厂类统一创建所有的具体产品而是针对不同的产品设计了不同的工厂每一个工厂只生产特定的产品。

    工厂方法模式结构

    从工厂方法模式简介中可以知道该模式有以下几种角色

  • 抽象工厂AbstractFactory所有生产具体产品的工厂类的基类提供工厂类的公共方法
  • 具体工厂ConcreteFactory生产具体产品的工厂
  • 抽象产品AbstractProduct所有产品的基类提供产品类的公共方法
  • 具体产品ConcreteProduct具体的产品类
  • UML类图

    在这里插入图片描述

    Version 2.0

    接下来继续使用生产手机的例子来讲解该模式

    一、定义抽象产品类AbstractProduct

    Phone类手机类AbstractProduct

    class Phone {public:virtual void make(void) 0;};

    二、定义具体产品类

    MiPhone类小米手机类Product1

    class MiPhone : public Phone {public:MiPhone() {this->make();}virtual void make(void) {cout << "make xiaomi phone!" << endl;}};

    IPhone类苹果手机类Product2

    class IPhone : public Phone {public:IPhone() {this->make();} virtual void make(void) {cout << "make iphone!" << endl;}};

    三、定义抽象工厂类AbstractFactory

    AbstractFactory类生产不同产品的工厂的抽象类

    class AbstractFactory {public:virtual Phone* makePhone(void) 0;};

    四、定义具体工厂类

    XiaoMiFactory类生产小米手机的工厂类ConcreteFactory1

    class XiaoMiFactory : public AbstractFactory {public:virtual Phone* makePhone(void) {return new MiPhone();}};

    AppleFactory类生产苹果手机的工厂类ConcreteFactory2

    class AppleFactory : public AbstractFactory {public:virtual Phone* makePhone(void) {return new IPhone();}};

    五、客户端

    int main(int argc, char** argv) {AbstractFactory* miFactory new XiaoMiFactory();AbstractFactory* appleFactory new AppleFactory();Phone* miPhone miFactory->makePhone();Phone* iPhone appleFactory->makePhone();return 0;}

    执行结果

    make xiaomi phone!make iphone!

    Version 2.1

    扩展增加生产华为手机实现

    一、扩展具体产品类

    Huawei类华为手机类Product3

    class HuaweiPhone : public Phone{public:HuaweiPhone() {this->make();}virtual void make(void) {cout << "make huawei phone!" << endl;}};

    二、扩展具体工厂类

    HuaweiFactory类生产华为手机的工厂类ConcreteFactory3

    class HuaweiFactory : public AbstractFactory {public:virtual Phone* makePhone(void) {return new HuaweiPhone();}};

    三、扩展客户端

    int main(int argc, char** argv) {AbstractFactory* miFactory new XiaoMiFactory();AbstractFactory* appleFactory new AppleFactory();AbstractFactory* huaweiFactory new HuaweiFactory();Phone* miPhone miFactory->makePhone();Phone* iPhone appleFactory->makePhone();Phone* huaweiphone huaweiFactory->makePhone();return 0;}

    执行结果

    make xiaomi phone!make iphone!make huawei phone!

    优点

  • 工厂方法用于创建客户所需产品同时向客户隐藏某个具体产品类将被实例化的细节用户只需关心所需产品对应的工厂。
  • 工厂自主决定创建何种产品并且创建过程封装在具体工厂对象内部多态性设计是工厂方法模式的关键。
  • 新加入产品时无需修改原有代码增强了系统的可扩展性符合开闭原则。
  • 缺点

  • 添加新产品时需要同时添加新的产品工厂系统中类的数量成对增加增加了系统的复杂度更多的类需要编译和运行增加了系统的额外开销。
  • 适用场合

  • 客户端不需要知道它所需要创建的对象的类。
  • 抽象工厂类通过其子类来指定创建哪个对象。
  • 抽象工厂模式(Abstract Factory)

    定义

    提供一个创建一系列相关或相互依赖对象的接口而无需指定他们具体的类。

    简言之一个工厂可以提供创建多种相关产品的接口而无需像工厂方法一样为每一个产品都提供一个具体工厂。

    抽象工厂模式结构

    抽象工厂模式结构与工厂方法模式结构类似不同之处在于一个具体工厂可以生产多种同类相关的产品

  • 抽象工厂AbstractFactory所有生产具体产品的工厂类的基类提供工厂类的公共方法
  • 具体工厂ConcreteFactory生产具体产品的工厂
  • 抽象产品AbstractProduct所有产品的基类提供产品类的公共方法
  • 具体产品ConcreteProduct具体的产品类
  • UML类图

    在这里插入图片描述

    Version 3.0

    一、定义A类抽象产品类AbstractProductA

    Phone类定义手机产品的接口(AbstractPhone)

    class Phone {public:virtual void make(void) 0;};

    二、定义具体A类产品类

    MiPhone类小米手机类Product1

    class MiPhone : public Phone {public:MiPhone() {this->make();}virtual void make(void) {cout << "make xiaomi phone!" << endl;}};

    IPhone类苹果手机类Product2

    class IPhone : public Phone {public:IPhone() {this->make();} virtual void make(void) {cout << "make iphone!" << endl;}};

    三、定义B类抽象产品类 AbstractProductB

    PC类定义PC产品的接口(AbstractPC)

    class PC {public:virtual void make(void) 0;};

    四、定义具体B类产品类

    小米PC类定义小米电脑产品(MIPC)

    class MiPC : public PC {public:MiPC() {this->make();}virtual void make(void) {cout << "make xiaomi PC!" << endl;}};

    MAC类定义苹果电脑产品(MAC)

    class MAC : public PC {public:MAC() {this->make();}virtual void make(void) {cout << "make MAC!" << endl;}};

    五、定义抽象工厂AbstractFactory

    AbstractFactory类

    class AbstractFactory {public:virtual Phone* makePhone(void) 0;virtual PC* makePC(void) 0;};

    六、定义具体工厂ConcreteProduct

    XiaoMiFactory类小米工厂类ConcreteFactory1

    class XiaoMiFactory : public AbstractFactory {public:virtual Phone* makePhone(void) {return new MiPhone();}virtual PC* makePC(void) {return new MiPC();}};

    AppleFactory类苹果工厂类ConcreteFactory2

    class AppleFactory : public AbstractFactory {public:virtual Phone* makePhone(void) {return new IPhone();}virtual PC* makePC(void) {return new MAC();}};

    七、客户端

    int main(int argc, char** argv) {AbstractFactory* miFactory new XiaoMiFactory();AbstractFactory* appleFactory new AppleFactory();Phone* miPhone miFactory->makePhone();PC* miPC miFactory->makePC();Phone* iPhone appleFactory->makePhone();PC* Mac appleFactory->makePC();return 0;}

    执行结果

    make xiaomi phone!make xiaomi PC!make iphone!make MAC!

    优点

  • 抽象工厂方法用于创建客户所需产品同时向客户隐藏某个具体产品类将被实例化的细节用户只需关心所需产品对应的工厂。
  • 新加入产品系列时无需修改原有系统增强了系统的可扩展性符合开闭原则。
  • 缺点

  • 在已有产品系列中添加新产品时需要修改抽象层代码对原有系统改动较大违背开闭原则。
  • 适用场合

  • 一系列/家族产品需要被同时使用时适合使用抽象工厂模式。
  • 产品结构稳定设计完成之后不会向系统中新增或剔除某个产品。
  • 网友评论