设计模式二十二:state(状态模式)——对象行为型模式

state(状态模式)——对象行为型模式

 

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

 


2.别名
政策(policy)

 


3.动机
将算法硬编码进使用他们的类中是不可取的
算法过于复杂
有时候需要不同的算法
增加新的换行算法或者改变现有的算法将变得非常困难

 


4.适用性
1)许多相关的类仅仅是行为有异。策略提供了一种用多个行为中的一个行为来配置一个类的方法。
2)需要使用一个算法的不同变体
3)算法使用客户不应该知道的数据。可以使用策略模式以避免暴露复杂的、与算法相关的数据结构。
4)一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,将相关的条件分支移入他们各自的strategy类中以替代这些条件语句。

 


5.结构

参考:http://www.cnblogs.com/cj723/archive/2007/03/21/682479.html

 

 

6.参与者
strategy策略
定义所有支持的算法的公共接口
concretestrategy具体策略
以strategy接口实现某具体算法
context上下文
用一个concretestrategy对象来配置
维护一个对strategy对象的引用
可定义一个接口来让strategy访问它的数据

 


7.协作
strategy和context相互作用以实现选定的算法
context将他的用户的请求转发给它的strategy

 


8.效果
优点
1)相关算法系列
2)一个替代继承的方法
3)消除了一些条件语句
4)实现的选择
缺点
5)客户必须要了解所有的strategy
6)strategy和context之间的通信开销
7)增加对象的数目

 


9.实现
1)定义strategy和context接口
必须使concretestrategy能有效访问context中的所有数据
一种方法是context将数据放在参数中传递给strategy
另一种方法是将context传递给strategy
2)将strategy作为模板参数
3)使strategy对象成为可选的

 

 

10.代码示例

#include<iostream>
using namespace std;

class calculate
{
    public:
    calculate(double di,double m)
    {
        dis = di;
        money = m;
    }
    char getName()
    {
        return name;
    }
    virtual double getRes(){return 0;}
    protected:
    double money;
    char name;
    double dis;
};

class noDiscount:public calculate
{
    public:
    noDiscount(double di,double m):calculate(di,m)
    {
        cout<<"no discount "<<endl;
        dis = di;
        money = m;
        name = 'n';
    }
    double getRes()
    {
        return money;
    }
};

class discount:public calculate
{
    public:
    discount(double di,double m):calculate(di,m)
    {
        cout<<"create discount strategy: money*(1-dis*1.0/100)"<<endl;
        dis = di;
        money = m;
        name = 'd';
    }
    double getRes()
    {
        return money*(1-dis*1.0/100);
    }
};

class returnMoney:public calculate
{
    public:
    returnMoney(double di,double m):calculate(di,m)
    {
        cout<<"create return money strategy: money-dis"<<endl;
        dis = di;
        money = m;
        name = 'r';
    }
    double getRes()
    {
        if(money>=100)
            return money-dis;
        else
            return money;
    }
};

class sale
{
    public:
    sale(double m, double di, char str)
    {
        dis = di;
        money = m;
        strategy = str;
        cal = 0;
    }
    void setStrategy(char c)
    {
        strategy = c;
    }
    double calculateMoney()
    {
        switch (strategy)
        {
        case 'd':
            cal = new discount(dis, money);
            break;
        case 'r':
            cal = new returnMoney(dis, money);
            break;
        default:
            cal = new noDiscount(dis, money);
        }
        cout<<"you need to pay money "<<cal->getRes()<<endl;    
    }
    private:
    calculate *cal;
    char strategy;
    double dis;
    double money;
};

int main()
{
    sale *s = new sale(180, 10, 'p');
    s->calculateMoney();
    s->setStrategy('d');
    s->calculateMoney();
    s->setStrategy('r');
    s->calculateMoney();
}

 

 

11.相关模式
flyweight
strategy对象经常是很好的轻量级对象。

 

 

posted @ 2012-05-22 22:10  w0w0  阅读(200)  评论(0编辑  收藏  举报