一、简单工厂模式
1.1 简介
创建型模式关注对象的创建过程;
创建型模式描述如何将对象的创建和使用分离,让用户在使用对象过程中无须关心对象的创建细节,从而降低系统耦合度,并且让系统易于修改和扩展。
其实简单工厂模型并不属于Gof的23种设计模式,但应用也十分频繁,同时也是其余创建模式的基础,因此有必要先学习简单工厂模式。
如下栗子:客户Jungle需要时可以向工厂Factory提供产品参数,工厂根据产品参数生产对应产品,客户Jungle并不需要关心产品的生产过程细节。
简单工厂模式的定义:
定义一个简单工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类
1.2 简单工厂的实现流程
设计一个抽象产品类,它包含一些公共方法的实现;
从抽象产品类中派生出多个具体产品类,如篮球类、足球类、排球类,具体产品类中实现具体产品生产的相关代码;
设计一个工厂类,工厂类中提供一个生产各种产品的工厂方法,该方法根据传入参数(产品名称)创建不同的具体产品类对象;
客户只需调用工厂类的工厂方法,并传入具体产品参数,即可得到一个具体产品对象。
二、简单工厂模式结构
2.1 代码结构
//抽象产品类AbstractProduct class AbstractProduct { public: //抽象方法: }; //具体产品类Basketball class ConcreteProduct :public AbstractProduct { public: //具体实现方法 }; class Factory { public: AbstractProduct createProduct(string productName) { AbstractProduct pro = NULL; if (productName == "ProductA"){ pro = new ProductA(); } else if (productName == "ProductB"){ pro = new ProductB(); } ... } };
客户端使用:创建一个工厂对象,调用工厂对象的createProduct
方法,并传入所需要的产品参数,即可得到所需产品的实例对象,客户不需要关心产品的创建细节。
2.2 简单工厂模式的栗子
(1)抽象产品类AbstractProduct
抽象方法不提供实现。
#include<iostream> #include<string> using namespace std; //抽象产品类AbstractProduct class AbstractSportProduct { public: AbstractSportProduct(){ } //抽象方法: void printName(){}; void play(){}; };
(2)定义三个具体产品类
//具体产品类Basketball class Basketball :public AbstractSportProduct { public: Basketball(){ printName(); play(); } //具体实现方法 void printName(){ printf("Andy get Basketball\n"); } void play(){ printf("Andy play Basketball\n"); } }; //具体产品类Football class Football :public AbstractSportProduct { public: Football(){ printName(); play(); } //具体实现方法 void printName(){ printf("Andy get Football\n"); } void play(){ printf("Andy play Football\n"); } }; //具体产品类Volleyball class Volleyball :public AbstractSportProduct { public: Volleyball(){ printName(); play(); } //具体实现方法 void printName(){ printf("Andy get Volleyball\n"); } void play(){ printf("Andy play Volleyball\n"); } };
(3)定义工厂类和工厂方法
//定义工厂类和工厂方法 class Factory { public: AbstractSportProduct *getSportProduct(string productName) { AbstractSportProduct *pro = NULL; if (productName == "Basketball"){ pro = new Basketball(); } else if (productName == "Football"){ pro = new Football(); } else if (productName == "Volleyball"){ pro = new Volleyball(); } return pro; } };
(4)客户端
#include <iostream> #include "SimpleFactory.h" int main() { printf("简单工厂模式\n"); //定义工厂类对象 Factory *fac = new Factory(); AbstractSportProduct *product = NULL; product = fac->getSportProduct("Basketball"); product = fac->getSportProduct("Football"); product = fac->getSportProduct("Volleyball"); system("pause"); return 0; }
代码运行结果如下:
在客户端使用时,只需要提供产品名称作为参数,传入工厂的方法中,即可得到对应产品。抽象产品类中并没有提供公共方法的实现,而是在各个具体产品类中根据各自产品情况实现,工厂类中有getSportProduct函数,其返回值为抽象类AbstractSportProduct型指针,该函数能分别进行实例化体育用具的对象。
三、小结
简单工厂模式的优点:
工厂类提供创建具体产品的方法,并包含一定判断逻辑,客户不必参与产品的创建过程;
客户只需要知道对应产品的参数即可,参数一般简单好记,如数字、字符或者字符串等。
简单工厂模式的缺点:
假设有一天Andy想玩棒球了,最简单的方法,即再从抽象产品类派生出一个Baseball类,并在工厂类的getSportProduct方法中增加“productName == "Baseball”的条件分支即可,但是这违背了开闭原则(对扩展开放,对修改关闭),即在扩展功能时修改了既有的代码。
另一方面,简单工厂模式所有的判断逻辑都在工厂类中实现,一旦工厂类设计故障,则整个系统都受之影响。