一、简单工厂模式

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;
}