工厂模式&&策略模式

工厂模式&&策略模式,第1张

文章目录
      • 1. 简单工厂模式
        • 1.1 内容
        • 1.2 优缺点
      • 2. 策略模式
        • 2.1 内容
        • 2.2 优点
      • 3. 工厂模式
        • 3.1 内容
      • 4. 工厂模式和策略模式的关系

这么大岁数了才开始研究设计模式,而且一直没有理解。


现在明白了,虽然我能看懂代码,但是感觉并没有领会其中的意思,主要的思想就是目前的需求能不能用这个模式,如果用,要怎么写。


1. 简单工厂模式 1.1 内容

有一堆有相同类型的类,它们叫做产品类,把它们的公共部分抽象出来,这样就生成了一个产品抽象类,这个类都是虚函数,具体的内容由子类实现。


另有一个工厂类,每个类都由工厂类负责实例化,我选择在工厂类的析构中删掉这个类。


将一堆类抽象出来基类是个很基本的 *** 作,简单工厂模式的核心在于这个工厂,即这些产品类要怎么实例化,简单工厂模式用一个工厂类进行实例化。


下面的代码是我自己写的,有三款手机,诺基亚、小米和谷歌,基类自然就是手机类,工厂类根据输入的类型决定生产什么产品。


#include

class mobile
{
    public:
        mobile() = default;
        virtual void brand(void) = 0;
        virtual ~mobile() = default;
};

class nokia : public mobile
{
    public:
        void brand(void)
        {
            std::cout<<"nokia"<brand();
    delete(nn);
    mobile* nnokia = Factory.create_project(Nokia);
    nnokia->brand();
    delete(nnokia);
    return 0;
}

客观问题来的时候,将可变的东西变成产品类。


例如要做一个软件系统,支持给货物打折,后续也可能支持返利,或者其它优惠活动,这种情况肯定就是把返利、打折做成产品子类,产品抽象类就是付款。


上面的方法delete为什么没放在析构里呢?因为放了就成了工厂和策略的集合,具体的看下面。


1.2 优缺点

特点:工厂类封装了创建具体产品对象的函数。



缺点:扩展性差,新增产品的时候需要修改工厂类。


例如再加一个一加,就要在工厂类中增加一个case。


2. 策略模式 2.1 内容

没太看明白策略,只看懂了策略+工厂。


和简单工厂一样,都是先在待扩展的内容中找到公共部分,抽象出父类,简单工厂中叫做产品抽象类,策略模式中叫算法类,也都没差。


更有意思的是,工厂类和上下文类又很像不是吗?都是在类内new一下,只不过简单工厂不存数据,直接把new出来的结果返回,策略+工厂替你保存结果。


策略+工厂和工厂的区别不仅仅是是否保存,简单工厂的话,使用者需要了解工厂类和抽象产品,因为用的是具体产品类接收的工厂类返回值。


然而策略+工厂根本不需要知道产品相关的任何类,因为都被封装在了上下文类的内部,调用什么函数context会替你做的,这样降低了耦合。


#include

class strategy
{
    public:
        strategy(void) = default;
        virtual ~strategy() = default;
        virtual double get_money(double) = 0;
};

class account : public strategy
{
    public:
        account(void) = default;
        virtual ~account() = default;
        double get_money(double get)
        {
            return get*0.8;
        }
};

class all : public strategy
{
    public:
        all(void) = default;
        virtual ~all() = default;
        double get_money(double get)
        {
            return get;
        }
};

class full_min : public strategy ///<不知道满减怎么说,瞎写吧
{
    public:
        full_min(void) = default;
        virtual ~full_min() = default;
        double get_money(double get)
        {
            return get>500 ? get-100 : get;
        }
};


enum details
{
    enum_account,
    enum_all,
    enum_full_min,
};
class Context
{
    public:
        strategy* cs;

        Context(const enum details &ss)
        {
            switch (ss)
            {
                case enum_account:
                    cs = new account;
                    break;
                case enum_all:
                    cs = new all;
                    break;
                case enum_full_min:
                    cs = new full_min;
                    break;
                default:
                    cs = nullptr;
                    break;
            }
        }

        virtual ~Context()
        {
            if(nullptr!=cs)
                delete(cs);
        }

        double get_result(double input)
        {
            return cs!=nullptr ? cs->get_money(input) : 0;
        }
};

int main(void)
{
    Context context(enum_account);
    std::cout<
2.2 优点

优点:
算法可以自由切换;
避免使用多重条件判断(如果不用策略模式我们可能会使用多重条件语句,不利于维护);
扩展性良好,增加一个策略只需实现接口即可。


缺点:
策略类数量会增多,每个策略都是一个类,复用的可能性很小;
所有的策略类都需要对外暴露。


3. 工厂模式 3.1 内容

简单工厂确实简单,但是如果新加一个运算的话就要去工厂中修改内容,也就违背了开放封闭原则(只加内容而不改代码)。


那是不是可以把工厂的那个case也抽象出来,这样每次增加需求就只增加类就可以了,不需要修改代码。



按照我的理解:switch-case是开放封闭原则的死敌
按照我的写法就是用抽象类替代需要修改的switch-case,这样没有太大的修改时就不需要动facotry类,只需要增加新的子工厂类就OK了。


话虽如此,但是工厂类的delete *** 作还是在外面完成的,和策略+工厂的方式比还差一些。


#include

class mobile
{
    public:
        mobile() = default;
        virtual void brand(void) = 0;
        virtual ~mobile() = default;
};

class nokia : public mobile
{
    public:
        void brand(void)
        {
            std::cout<<"nokia"<brand();
    delete(mobilephone);
    return 0;
}

下面是策略+工厂的写法,不过这里命名有点问题,肯定不应该叫做工厂,而且用工厂的思路来处理,工厂怎么能负责维护产品呢?他们只负责造,造出来就不管了。


所以工厂类的名字应该还是上下文,有一堆上下文,而这上下文策略子类确实是负责维护“产品”信息,所有对产品的 *** 作都通过对上下文的调用。


还是那句话,如果把上下文称为工厂必然就不合适了。


class factory
{
    public:
        factory() = default;
        virtual ~factory() = default;
};

class google_factory : public factory
{
    public:
        google_factory(void)
        {
            p_project = new google;
        }
        virtual ~google_factory()
        {
            delete(p_project);
            return;
        }
        void get_brand(void)
        {
            p_project->brand();
        }
    private:
        mobile* p_project;
};

int main(void)
{
    google_factory gf;
    gf.get_brand();
    return 0;
}
4. 工厂模式和策略模式的关系

就跟我之前想的是一样的,既然你要生产东西,工厂模式会把你想要的东西给你,要怎么用是你的事,因此用户也要会用产品才行,需要了解实际产品类和工厂类。


策略模式是不允许直接 *** 作子策略的,会由上下文包装后才行,所以你只要了解上下文类(对应工厂模式的工厂类)就可以了。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/578596.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-11
下一篇 2022-04-11

发表评论

登录后才能评论

评论列表(0条)