zoukankan      html  css  js  c++  java
  • 工厂模式

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

    简单工厂模式

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

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

    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" << '
    ';
        }
    };
    
    class CEllipseWhiteSoap : public IWhiteSoap
    {
    public:
        CEllipseWhiteSoap() {}
        ~CEllipseWhiteSoap() {}
        void show() override
        {
            std::cout << "prodece ellipse white soap" << '
    ';
        }
    };
    
    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" << '
    ';
        }
    };
    
    class CEllipseWhiteSoap : public IWhiteSoap
    {
    public:
        CEllipseWhiteSoap() {}
        ~CEllipseWhiteSoap() {}
        void show() override
        {
            std::cout << "prodece ellipse white soap" << '
    ';
        }
    };
    
    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" << '
    ';
            return new CRectangleWhiteSoap();
        }
    };
    
    class CFactoryEllipse : public IFactory
    {
    public:
        CFactoryEllipse() {}
        ~CFactoryEllipse() {}
        IWhiteSoap* createWhiteSoap() override
        {
            std::cout << "in Factory ellipse" << '
    ';
            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" << '
    ';
        }
    };
    
    class CEllipseWhiteSoap : public IWhiteSoap
    {
    public:
        CEllipseWhiteSoap() {}
        ~CEllipseWhiteSoap() {}
        void show() override
        {
            std::cout << "prodece ellipse white soap" << '
    ';
        }
    };
    
    
    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" << '
    ';
        }
    };
    
    class CEllipseYellowSoap : public IYellowSoap
    {
    public:
        CEllipseYellowSoap() {}
        ~CEllipseYellowSoap() {}
        void show() override
        {
            std::cout << "prodece ellipse Yellow soap" << '
    ';
        }
    };
    
    
    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;
    }
  • 相关阅读:
    h5页面页面在iphoneX手机上底部会有留白解决办法
    自定义单张图片放大预览功能,可支持手势缩放,依赖jquery
    js事件内部有click事件时,click事件会重复调用解决方法
    h5页面通过阿里云的broswer-js-sdk上传文件
    python字符串前加r、f、u、l 的区别
    Python基础面试题 :计算列表中出现最多次的字符
    python基础入门教程:传参是传值还是传引用
    Python 面试题:输入一个数组,输出该数组的第二大的数字
    Python 7种超实用的数据清洗方法,这你一定要掌握
    python教程:3个非常有用的内置函数(filter/map/reduce)
  • 原文地址:https://www.cnblogs.com/zuofaqi/p/10471886.html
Copyright © 2011-2022 走看看