• 简单工厂与策略模式


    简单工厂模式

           专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。它又称为静态工厂方法模式,属于类的创建型模式。简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。

    该模式中包含的角色及其职责:

    1、工厂(Creator)角色

         简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。

    2、抽象(Product)角色

      简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。

    3、具体产品(Concrete Product)角色

    简单工厂模式的特点:

         简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。不难发现,简单工厂模式的缺点也正体现在其工厂类上,由于工厂类集中了所有实例的创建逻辑,所以“高内聚”方面做的并不好。另外,当系统中的具体产品类不断增多时,可能会出现要求工厂类也要做相应的修改,扩展性并不很好。

    UML:

     

     

    策略模式

            定义一系列的算法,把他们一个个封装起来,并且使它们可以相互替换。策略模式让算法可以独立于使用它的客户而变化。

    适用性:

    1、许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。

    2、需要使用一个算法的不同变体。例如:你可能会定义一些反应不同的空间、时间权衡的算法。当这些变体为一个算法的类层次时,可以用本模式。

    3、算法使用客户不应该知道的数据。可适用策略模式避免暴露复杂、与算法相关的数据结构。

    4、一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。

    参与者:

    1、Strategy策略

          定义所以支持的算法的公共接口。

    2、ConcreteStrategy具体策略

          以strategy接口实现的具体算法。

    3、Context

          a.用一个ConcreteStrategy对象来配置。

          b.维护一个Strategy对象的引用。

          c.可定义一个接口来让Strategy访问它的数据。

    UML:

     

     

    简单工厂模式与策略模式的差异:

    1、用途不一样 
           工厂是创建型模式,它的作用就是创建对象; 
           策略是行为型模式,它的作用是让一个对象在许多行为中选择一种行为;

    2、关注点不一样 
           一个关注对象创建 
           一个关注行为的封装

    3、解决不同的问题 

         工厂模式是创建型的设计模式,它接受指令,创建出符合要求的实例;它主要解决的是资源的统一分发,将对象的创建完全独立出来,让对象的创建和具体的使用客户无关。主要应用在多数据库选择,类库文件加载等。 
         策略模式是将不同的算法封装成一个对象,这些不同的算法从一个抽象类或者一个接口中派生出来,客户端持有一个抽象的策略的引用,这样客户端就能动态的切换不同的策略。策略模式让策略的变化独立于使用策略的客户。

    代码:用简单方法实现两个数基本的算术运算!

    定义一个基类

    class Operation{
    public:
        Operation(double num1 = 0, double num2 = 0)
        {
            mNum1 = num1;
            mNum2 = num2;
        }
        virtual void setNum1(double num)
        {
            mNum1 = num;
        }
        virtual double getNum1()
        {
            return mNum1;
        }
        virtual void setNum2(double num)
        {
            mNum2 = num;
        }
        virtual double getNum2()
        {
            return mNum2;
        }
        virtual double getResult()
        {
            return 0;
        }
    private:
        double mNum1;
        double mNum2;
    };

    定义具体的运算类:

    class OperationAdd:public Operation{
    public:
        OperationAdd(double num1 = 0, double num2 = 0):Operation(num1, num2){}
    
        virtual double getResult();
    };
    
    class OperationSub: public Operation
    {
    public:
        OperationSub(double num1 = 0, double num2 = 0):Operation(num1, num2){}
    
        virtual double getResult();
    };
    
    class OperationMul:public Operation
    {
    public:
        OperationMul(double num1 = 0, double num2 = 0):Operation(num1, num2){}
        
        virtual double getResult();
    private:
    
    };
    
    class OperationDiv:public Operation{
    public:
        OperationDiv(double num1 = 0, double num2 = 0):Operation(num1, num2){}
    
        virtual double getResult();
    };

    运算方法具体实现:

    double OperationAdd::getResult()
    {
        return getNum1() + getNum2();
    }
    
    double OperationSub::getResult()
    {
        return getNum1() - getNum2();
    }
    
    double OperationMul::getResult()
    {
        return getNum1() * getNum2();
    }
    
    double OperationDiv::getResult()
    {
        double divisor = getNum2();
        if(divisor < 0.000001 && divisor > -0.000001)
        {
            return 0;
        }
        else
        {
            return getNum1() / getNum2();
        }
    }

    实现简单工厂方法:

    Operation* OperationFactory(char ch)
    {
        switch (ch)
        {
        case '+':
            return new OperationAdd();
            break;
        case '-':
            return new OperationSub();
            break;
        case '*':
            return new OperationMul();
            break;
        case '/':
            return new OperationDiv();
            break;
        default:
            return new Operation();
            break;
        }
    }

    客户端代码

        while(1)
        {
            cin>>num1;
            cin.clear();
            cin>>ch;
            cin.clear();
            cin>>num2;
            cin.clear();
            cin.ignore(std::numeric_limits<std::streamsize>::max(), '
    '); 
            Operation* pOper = OperationFactory(ch);
            pOper->setNum1(num1);
            pOper->setNum2(num2);
            cout<<num1<<ch<<num2<<"="<<pOper->getResult()<<endl;
        }

    修改:计算数A和数B不同运算的结果。

    简单工厂实现:

            int a = 22, b = 2;
        Operation* p = OperationFactory('+');
        p->setNum1(a);
        p->setNum2(b);
        cout<<p->getResult()<<endl;
    
        p = OperationFactory('-');
        p->setNum1(a);
        p->setNum2(b);
        cout<<p->getResult()<<endl;
    
        p = OperationFactory('*');
        p->setNum1(a);
        p->setNum2(b);
        cout<<p->getResult()<<endl;
    
        p = OperationFactory('/');
        p->setNum1(a);
        p->setNum2(b);
        cout<<p->getResult()<<endl;    

    策略模式实现:

    把题目理解成通过加、减、乘、除 四中策略实现对A、B的运算!

    增加类:Calculate

    class Calculate{
    public:
        Calculate(Operation* pOperation = OperationFactory('+')){mpOprt = pOperation;}
    
        void setOperation(char ch)
        {
            mpOprt = OperationFactory(ch);
        }
    
        void setNum1(double num1)
        {
            mpOprt->setNum1(num1);
        }
    
        void setNum2(double num2)
        {
            mpOprt->setNum2(num2);
        }
    
        double getResult()
        {
            return mpOprt->getResult();
        }
    
    private:
        Operation* mpOprt;
    };

    则客户端代码:

        int a = 22, b = 2;
        Calculate oneCal;
        oneCal.setNum1(a);
        oneCal.setNum2(b);
        cout<<oneCal.getResult()<<endl;
    
        oneCal.setOperation('-');
        oneCal.setNum1(a);
        oneCal.setNum2(b);
        cout<<oneCal.getResult()<<endl;
    
        oneCal.setOperation('*');
        oneCal.setNum1(a);
        oneCal.setNum2(b);
        cout<<oneCal.getResult()<<endl;
    
        oneCal.setOperation('/');
        oneCal.setNum1(a);
        oneCal.setNum2(b);
        cout<<oneCal.getResult()<<endl;

    与简单工厂的实现相比较,策略模式客户端只需要对一个对象进行操作,并没有涉及到具体的策略实现类,使运算算法与客户端策底的分离。

    而且策略模式更方便不同策略的切换!

  • 相关阅读:
    Codeforces 787B. Not Afraid
    Codeforces 670D. Magic Powder
    POJ 1979 Red and Black
    T1215:迷宫
    POJ 1163 The Triangle
    洛谷P1219 八皇后
    T1212:LETTERS
    T1317:【例5.2】组合的输出
    洛谷P1706 全排列问题
    codevs 5971 打击犯罪
  • 原文地址:https://www.cnblogs.com/wrbxdj/p/5251901.html
Copyright © 2020-2023  润新知