简单工厂模式/工厂方法模式/抽象工厂模式
一、简单工厂模式
1. 定义
简单工厂模式属于创建型模式又叫做静态工厂方法模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。
2. 结构图
Factory:工厂类,简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
IProduct:抽象产品类,简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
Product:具体产品类,是简单工厂模式的创建目标。
3. 场景以及实现
有一个电脑生产工厂,他除了能生产联想电脑,还能生产小米电脑、惠普电脑。
抽象产品类
//抽象电脑类 class Computer { public: virtual void ShowName() = 0; };
具体产品类
//联想 class LenovoComputer :public Computer { public: virtual void ShowName(){ cout << "联想电脑!" << endl; } }; //小米 class MIComputer :public Computer { public: virtual void ShowName(){ cout << "小米电脑!" << endl; } }; //惠普 class HpComputer :public Computer { public: virtual void ShowName(){ cout << "惠普电脑!" <<endl; } };
电脑工厂类
class ComputerFactory{ public: static Computer* CreateComputer(string type){ Computer *mComputer = nullptr; if (type == "lenovo"){ mComputer = new LenovoComputer(); } else if (type == "hp"){ mComputer = new HpComputer(); } else if (type == "mi"){ mComputer = new MIComputer(); } return mComputer; } };
客户端调用
ComputerFactory* factory = new ComputerFactory; Computer* m_Computer = factory->CreateComputer("lenovo"); m_Computer->ShowName(); delete m_Computer; m_Computer = factory->CreateComputer("hp"); m_Computer->ShowName(); delete m_Computer; m_Computer = factory->CreateComputer("mi"); m_Computer->ShowName(); delete m_Computer; delete factory;
4. 优缺点分析
4.1 优点
- 客户端只知道传入工厂类的参数,对于如何创建对象不关心,客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。
- 使用户根据参数获得对应的类实例,避免了直接实例化类,降低了耦合性。
4.2 缺点
- 违背了开放封闭原则
在工厂类中包含了必要的逻辑判断,根据不同的条件来动态实例化相关的类,对客户端来说,去除了与具体产品的依赖,与此同时也会带来一个问题:如果我们去增加产品,比如我们要生产苹果电脑,那我们就需要在工厂类中在添加一个Case分支条件,这违背了开放封闭原则。则我们需要更改工厂类中的源代码。于是便引出了工厂方法模式。
二、 工厂方法模式
解决了简单工厂模式违背开放封闭原则的缺点
#define CRT SECURE NO WARNINGS #include<iostream> #include<string> using namespace std; //抽象水果 class AbstractFruit{ public: virtual void ShowName() = 0; }; //苹果 class Apple :public AbstractFruit{ public: virtual void ShowName(){ cout << "我是苹果!" << endl; } }; //香蕉 class Banana :public AbstractFruit{ public: virtual void ShowName(){ cout << "我是香蕉!" << endl; } }; //抽象工厂 class AbstractFruitFactory{ public: virtual AbstractFruit*CreateFruit() = 0; }; // 苹果工厂 class AppleFactory :public AbstractFruitFactory { public: virtual AbstractFruit*CreateFruit(){ return new Apple; } }; //香蕉工厂 class BananaFactory :public AbstractFruitFactory{ public: virtual AbstractFruit*CreateFruit(){ return new Banana; } }; /** 增加的鸭梨和鸭梨工厂 class Pear :public AbstractFruit{ public: virtual void ShowName(){ cout << "我是鸭梨!" <<endl; } }; class PearFactory :public AbstractFruitFactory { public: virtual AbstractFruit* CreateFruit(){ return new Pear; } }; **/ void test01() { AbstractFruitFactory*factory = NULL; AbstractFruit*fruit = NULL; //创建一个苹果工厂 factory = new AppleFactory; //创建苹果 fruit = factory->CreateFruit(); fruit->ShowName(); delete fruit; delete factory; //创建一个香蕉工厂 factory = new BananaFactory; //创建香蕉 fruit = factory->CreateFruit(); fruit->ShowName(); delete fruit; delete factory; /** 调用新增的鸭梨工厂生产鸭梨 factory = new PearFactory; fruit = factory->CreateFruit(); fruit->ShowName(); delete fruit; delete factory; **/ } int main() { test01(); return 0; }
优点:工厂方法模式最大的特点是实例化不同的工厂生产不同的产品,如果需要扩展,则只需要增加新的工厂类和产品类就行了,不需要改基类。比如以上增加和生产鸭梨
缺点:一个工厂只能生产一种产品。当产品过多时,类过多。
三、 抽象工厂模式
抽象工厂模式和工厂方法模式很相似。最大的区别就是抽象工厂模式不止一个产品簇,并且每个工厂都不止生产一种产品。比如在工厂方法模式中,不同的工厂可以生产不同的产品。比如键盘、鼠标。分别由键盘工厂和鼠标工厂,但是智能生产一种键盘和鼠标。但是在抽象工厂模式中,每个工厂可以生产键盘和鼠标。还可以生产不同牌子的键盘和鼠标。说到这里,其实抽象工厂模式可以和简单工厂模式结合起来,来创建不同的工厂。
#include <iostream> // 键盘 class KeyBoard { public: virtual void show() = 0; }; // 微软的键盘 class KeyBoardMicro : public KeyBoard { public: void show() { std::cout << "微软的键盘" << std::endl; } }; // 联想的键盘 class KeyBoardLenovo : public KeyBoard { public: void show() { std::cout << "联想的键盘" << std::endl; } }; // 鼠标 class Mouse { public: virtual void show() = 0; }; class MouseMicro : public Mouse { public: void show() { std::cout << "微软的鼠标" << std::endl; } }; class MouseLenovo : public Mouse { public: void show() { std::cout << "联想的鼠标" << std::endl; } }; // 工厂 class Factory { public: virtual KeyBoard * createKeyBoard() = 0; virtual Mouse * createMouse() = 0; }; // 微软的工厂 class FactoryMicro : public Factory { public: KeyBoard * createKeyBoard() { return new KeyBoardMicro(); } Mouse * createMouse() { return new MouseMicro(); } }; // 联想的工厂 class FactoryLenovo : public Factory { public: KeyBoard * createKeyBoard() { return new KeyBoardLenovo(); } Mouse * createMouse() { return new MouseLenovo(); } }; int main() { using namespace std; Factory * p = new FactoryMicro(); KeyBoard * pKeyBoard = p->createKeyBoard(); Mouse * pMouse = p->createMouse(); pKeyBoard->show(); pMouse->show(); delete pMouse; delete pKeyBoard; delete p; p = new FactoryLenovo(); pKeyBoard = p->createKeyBoard(); pMouse = p->createMouse(); pKeyBoard->show(); pMouse->show(); delete pMouse; delete pKeyBoard; delete p; return 0; }