设计模式笔记-Strategy策略模式

来源:互联网 发布:bandicam mac版 编辑:程序博客网 时间:2024/06/15 22:10

策略模式,它解决的问题与前一篇Template模式类似,都是为了给逻辑(算法)具体实现和抽象接口之间的解耦。策略模式将接口的实现放在被组合对象中,将抽象接口放在组合类中。策略模式使得算法可以在不影响到客户端的情况下进行替换。它与模板模式的区别是:GoF的设计模式那本书里有这么一句话:"Template methods use inheritance to vary part of an algorithm. Strategies use delegation to vary the entire algorithm."看到这句话估计大家就明白了,策略模式使用组合的方式,允许“整个算法”的替换,而模板模式使用继承的方式,各个具体算法派生类有公共接口,也有各自不同的实现。这基本上也是继承与组合的区别。

以缓冲区替换算法为例,UML图如下:


有几点:

1. 在Cache类中组合了一个ReplaceAlgorithm *类型的指针。这时候在Client中使用时,需要先new一个具体的替换算法对象,然后将该对象的指针传递到Cache构造函数中!这暴露了算法的定义,用户必须对所有算法都有一个掌握--这貌似也是应该的,你都不知道它干什么的,怎么用它!

int main(){Cache cache(new LRU_ReplaceAlgorithm()); //暴露了算法的定义cache.Replace();return 0;}
2. 也可以用枚举方式定义算法类型,在Replace函数中传入算法类型参数,类似简单工厂模式!

//Cache需要用到替换算法enum RA {LRU, FIFO, RANDOM}; //标签class Cache{private:ReplaceAlgorithm *m_ra;public:Cache(enum RA ra) { if(ra == LRU)m_ra = new LRU_ReplaceAlgorithm();else if(ra == FIFO)m_ra = new FIFO_ReplaceAlgorithm();else if(ra == RANDOM)m_ra = new Random_ReplaceAlgorithm();else m_ra = NULL;}~Cache() { delete m_ra; }void Replace() { m_ra->Replace(); }};
这些都不是重点!
有人可能奇怪,我定义一个函数,里面用if-else语句判断,用户传进来什么参数,我用什么算法,不行吗?当然行,不过这种做法太落后了,不利于扩展,比如:什么时候想多加一个算法,那你得再加一个else语句,这种修改原来代码的行为是架构设计的忌讳,违反了“对扩展开放 对修改关闭”的原则,它比继承的办法还落后!哎,我也没体会到模式的好处,可能是自己造诣不够,做的项目不够大!

与状态模式区别:在解决的问题上,状态模式是解决内在状态的改变,而策略模式是解决内部算法的改变。在解决的方法上,状态模式是自我控制状态的改变,而策略模式是由外部制定使用啥策略。State模式注重的是对象在不同状态下的操作,它的具体实现类中有一个指向Context的引用,而Strategy没有。

0 0
原创粉丝点击