名称 | 策略模式 |
目的 | 解决类(Class)行为的不确定性问题 |
方法 | 将行为或特性向上进行抽象,通过对抽象的不同实现,避免了对原有代码的修改,从而便于扩展 |
场景:
1、假设现在有一个类A,同时它具有打印字母A跟写入字母A两个方法。
2、现在假设需要把Class A的printA()方法改为打印字母B,按照上面的设计,则必须修改Class A的代码,这违背了设计模式“对扩展开放,对修改关闭”的原则,给代码的维护和扩展带来了困难。
3、因为当前printA()方法需要(或者将来可能需要)变化,而writeA()当前不需要变化。为了解决这个问题,将代码结构进行重新设计如下:
a、保留Class A 原有的writeA()方法(因为暂时还不需要修改)
b、为了适应printA()方法的变化,让Class A可以随意打印,通过抽象,添加PrintBehavior接口,PrintBehavior接口包含printString()方法。这样,要想打印A,或者打印B,甚至是其他的 CDEF...,只需要实现PrintBehavior接口。对于Class A,不在关心到底打印的是A还是B或者其他,只需要执行PrintBehavior接口的pringString()方法即可,具体打印什么,由调用了PrintBehavior接口的哪个实现类决定。仔细分析,打印A和打印B现在还是需要在Class A中进行修改,为了解决这个问题,可在Class A 中添加PrintBehavior的set方法,如下;
至此,将打印A修改为打印B,只需要 new 一个实现了PrintBehavior接口的Print B类,并通过Class A 的setPrintBehavior接口定义即可。对于Class A,打印时仅需执行PrintBehavior.printString(),而具体打印的内容(变化的部分),则移到了Class A的外部。
摘抄GOF的定义如下:
Strategy :Define a family of algorithms,encapsulate each one,and make them interchangeable.Strategy lets the algorithm vary independently from clients that use it.
策略模式:定义了算法族,分别封装起来,让他们之间可以相互替换,此模式让算法额变化独立于使用算法的客户。
对于Strategy模式来说,主要有如下优点:
1、 提供了一种替代继承的方法,而且既保持了继承的优点(代码重用)还比继承更灵活(算法独立,可以任意扩展)。
2、 避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。
3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。
对于Strategy模式来说,主要有如下缺点:
1、 因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。
注:
1、以上内容虽参考了多位大牛和经典,然鄙猿不才,理解难免有不到位之处,欢迎看到本文的朋友多多提意见,多谢。
2、有些人说设计模式不实用,但静心思考,设计模式确是编程的艺术,一个个模式间流露了多少思维的灵动和严密。程序猿的生活不是枯燥的代码堆积。共勉。
参考及感谢
书籍:
《设计模式——可复用面向对象软件的基础》
《Head First Design Patterns》
博文:
http://www.cnblogs.com/justinw/archive/2007/02/06/641414.html#2693814
视频:
尚学堂马士兵老师的设计模式视频