工厂模式

工厂模式分为三类:简单工厂模式、工厂方法模式、抽象工厂模式。

简单工厂模式

特点是需要在工厂类中做判断,从而创造相应的产品。当增加新的产品时,就需要修改工厂类。

比如一家生产肥皂的工厂,它只有一家工厂,能够生产两种形状的白色肥皂,客户需要什么形状的,需要显示告诉工厂。

UML

 

#include <iostream>

enum EShape
{
    ERECTANGLE,
    EELLIPSE,
};

class IWhiteSoap
{
public:
    IWhiteSoap() {}
    virtual ~IWhiteSoap() {}
    virtual void show() = 0;
};

class CRectangleWhiteSoap : public IWhiteSoap
{
public:
    CRectangleWhiteSoap() {}
    ~CRectangleWhiteSoap() {}
    void show() override
    {
        std::cout << "produce rectangle white soap" << '\n';
    }
};

class CEllipseWhiteSoap : public IWhiteSoap
{
public:
    CEllipseWhiteSoap() {}
    ~CEllipseWhiteSoap() {}
    void show() override
    {
        std::cout << "prodece ellipse white soap" << '\n';
    }
};

class CFactory
{
public:
    CFactory() {}
    ~CFactory() {}
    
    IWhiteSoap* createSoap(enum EShape shape)
    {
        switch (shape)
        {
        case ERECTANGLE:
            return new CRectangleWhiteSoap();
            break;
        case EELLIPSE:
            return new CEllipseWhiteSoap();
            break;
        default:
            return nullptr;
            break;
        }
    }
};

int main()
{
    CFactory f;

    IWhiteSoap* p1 = f.createSoap(ERECTANGLE);
    p1->show();

    IWhiteSoap* p2 = f.createSoap(EELLIPSE);
    p2->show();

    delete p1;
    delete p2;

    return 0;
}

 工厂方法模式

简单工厂的缺点就是,当需要增加新的形状时,需要修改工厂类,这就违背了开放封闭原则。工厂方法可以解决这个问题。工厂方法模式就是,定义一个用于创建对象的接口,让子类决定实例化哪个类。

肥皂工厂从一个工厂变成了两个工厂,一个专门生产矩形的肥皂,一个专门生产椭圆形的肥皂。如果要增加新的形状,就需要增加新的工厂

UML

#include <iostream>

enum EShape
{
    ERECTANGLE,
    EELLIPSE,
};

class IWhiteSoap
{
public:
    IWhiteSoap() {}
    virtual ~IWhiteSoap() {}
    virtual void show() = 0;
};

class CRectangleWhiteSoap : public IWhiteSoap
{
public:
    CRectangleWhiteSoap() {}
    ~CRectangleWhiteSoap() {}
    void show() override
    {
        std::cout << "produce rectangle white soap" << '\n';
    }
};

class CEllipseWhiteSoap : public IWhiteSoap
{
public:
    CEllipseWhiteSoap() {}
    ~CEllipseWhiteSoap() {}
    void show() override
    {
        std::cout << "prodece ellipse white soap" << '\n';
    }
};

class IFactory
{
public:
    IFactory() {}
    virtual ~IFactory() {}
    virtual IWhiteSoap* createWhiteSoap() = 0;
};

class CFactoryRectangle : public IFactory
{
public:
    CFactoryRectangle() {}
    ~CFactoryRectangle() {}
    IWhiteSoap* createWhiteSoap() override
    {
        std::cout << "in Factory rectangle" << '\n';
        return new CRectangleWhiteSoap();
    }
};

class CFactoryEllipse : public IFactory
{
public:
    CFactoryEllipse() {}
    ~CFactoryEllipse() {}
    IWhiteSoap* createWhiteSoap() override
    {
        std::cout << "in Factory ellipse" << '\n';
        return new CEllipseWhiteSoap();
    }
};

int main()
{
    IFactory *p = new CFactoryEllipse();
    IWhiteSoap* soap = p->createWhiteSoap();

    soap->show();

    delete p;
    delete soap;

    return 0;
}

抽象工厂模式

如果这家工厂通过市场调查,发现黄色的肥皂销量很好,计划增加黄色肥皂的生产。简单工厂和工厂方法就无法实现了。这时,可以使用抽象工厂。

抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。

优点:

  • 封装了产品的创建,使得不需要知道具体是哪种产品,只需要知道是哪个工厂即可。
  • 可以支持不同类型的产品,使得模式灵活性更强。
  • 可以非常方便的使用一族中的不同类型的产品。

缺点:

  • 结构过于臃肿,如果产品类型较多或产品族较多,会非常难于管理。
  • 每次如果添加一组产品,那么所有的工厂类都必须添加一个方法,这样违背了开放-封闭原则。所以一般适用于产品组合产品族变化不大的情况。

以这家工厂为例,还是两个工厂,一个专门生产矩形的白色黄色肥皂,一个专门生产椭圆形的白色黄色肥皂。

UML

#include <iostream>

class IWhiteSoap
{
public:
    IWhiteSoap() {}
    virtual ~IWhiteSoap() {}
    virtual void show() = 0;
};

class CRectangleWhiteSoap : public IWhiteSoap
{
public:
    CRectangleWhiteSoap() {}
    ~CRectangleWhiteSoap() {}
    void show() override
    {
        std::cout << "produce rectangle white soap" << '\n';
    }
};

class CEllipseWhiteSoap : public IWhiteSoap
{
public:
    CEllipseWhiteSoap() {}
    ~CEllipseWhiteSoap() {}
    void show() override
    {
        std::cout << "prodece ellipse white soap" << '\n';
    }
};


class IYellowSoap
{
public:
    IYellowSoap() {}
    virtual ~IYellowSoap() {}
    virtual void show() = 0;
};

class CRectangleYellowSoap : public IYellowSoap
{
public:
    CRectangleYellowSoap() {}
    ~CRectangleYellowSoap() {}
    void show() override
    {
        std::cout << "produce rectangle Yellow soap" << '\n';
    }
};

class CEllipseYellowSoap : public IYellowSoap
{
public:
    CEllipseYellowSoap() {}
    ~CEllipseYellowSoap() {}
    void show() override
    {
        std::cout << "prodece ellipse Yellow soap" << '\n';
    }
};


class IFactory
{
public:
    IFactory() {}
    virtual ~IFactory() {}
    virtual IWhiteSoap* createWhiteSoap() = 0;
    virtual IYellowSoap* createYellowSoap() = 0;
};

class CFactoryRectangle : public IFactory
{
public:
    CFactoryRectangle() {}
    ~CFactoryRectangle() {}
    IWhiteSoap* createWhiteSoap() override
    {
        return new CRectangleWhiteSoap();
    }
    IYellowSoap* createYellowSoap() override
    {
        return new CRectangleYellowSoap();
    }
};

class CFactoryEllipse : public IFactory
{
public:
    CFactoryEllipse() {}
    ~CFactoryEllipse() {}
    IWhiteSoap* createWhiteSoap() override
    {
        return new CEllipseWhiteSoap();
    }
    IYellowSoap* createYellowSoap() override
    {
        return new CEllipseYellowSoap();
    }
};


int main()
{
    IFactory *factory = new CFactoryEllipse();
    IWhiteSoap* whitesoap = factory->createWhiteSoap();
    IYellowSoap* yellosoap = factory->createYellowSoap();

    whitesoap->show();
    yellosoap->show();

    delete factory;
    delete whitesoap;
    delete yellosoap;

    return 0;
}

 

posted @ 2019-03-05 10:37  二狗啸地  阅读(175)  评论(0编辑  收藏  举报