策略模式的机构
策略模式是对算法的包装,是把使用算法的责任和算法的实现分离开来,交给不同的对象管理。策略模式通常是把一系列算法包装到一系列策略类的子类。用一句话来说,就是:准备一组算法,将每个算法都包装起来,使得他们可以互换。下面是一个示意性的实现讲解策略模式实例的结构:
这个模式涉及到三个角色:
环境(context)角色:持有也抽象策略(Strategy)的引用;
抽象策略(Strategy)角色:这是一个抽象角色,通常由接口或者抽象类实现。此角色给出所有具体策略类所需的接口;
具体策略(ConcreteStrategy)角色:包装了所有算法或行为;
使用场景
假设要设计一个贩卖各种书籍的电子商务网站的购物车系统。一个最简单的场景就是把所有货品的单价乘以数量,可实际情况要比这个复杂。例如:本网站的所有高级会员享有8折优惠的促销价,中级会员享有9折的促销价,初级会员没有折扣。
跟据描述,折扣是要根据以下算法中的一个进行的:
1.对初级会员没有折扣;
2.对中级会员有9折优惠;
3.对高级会有有8折优惠;
用策略模式来是实现的结构如下:
源代码
抽象折扣类
/** *@类说明:抽象折扣类 */ public interface MemberStrategy{ /** *计算图书的价格 *@param bookPrice 图书的原价格 *@return 计算打折后的价格 */ public double calcPrice(double bookPrice); }
初级会员折扣类
/** *@类说明:初级会员折扣类 */ public class PrimaryMemberStrategy implements MemberStrategy{ /** *@param bookPrice 图书的原价格 *@return 图书打折后的价格 */ public double calcPrice(double bookPrice){ System.out.println("初级会员没有优惠"); return bookPrice; } }
中级会员折扣类
/** *@类说明:中级会员折扣类 */ public class IntermediateMemberStrategy implements MemberStrategy{ /** *@param bookPrice 图书的原价格 *@return 图书打折后的价格 */ public double calcPrice(double bookPrice){ System.out.println("中级会员享有9折优惠"); return bookPrice*0.9; } }
高级会员折扣类
/** *@类说明:高级会员折扣类 */ public class AdvanceMemberStrategy implements MemberStrategy{ /** *@param bookPrice 图书的原价格 *@return 图书打折后的价格 */ public double calcPrice(double bookPrice){ System.out.println("高级会员享有8折优惠"); return bookPrice*0.8; } }
价格类
/** *@类说明:价格类 */ public class Price{ //持有一个具体的策略类对象 private MemberStrategy memberStrategy; /** *构造方法,传入一个具体的策略类对象 *@param memberStrategy 具体的策略类对象 */ public Pirce(MemberStrategy memeberStrategy){ this.memberStrategy = memberStrategy; } /** *计算图书的价格 *@param bookPrice 图书原价 *@return 打折后的图书价格 */ public double quote(double bookPrice){ return memberStrategy.calcPrice(bookPrice); } }
客户端
/** *@类说明:客户端 */ public class Clint{ public static void main(String agr[]){ //选择并创建需要使用的策略类对象 MemberStrategy strategy = new AdvanceMemberStrategy(); //创建环境 Price price = new Price(strategy); //计算图书价格 double quote = price.quote(299.0); System.out.println("图书的最终价格是”+quote+"元"); } }
从上面的例子可以看出,策略模式仅仅封装算法,提供新的算法添加到系统中,以及老算法从系统中“退休”的方法。策略模式并不决定在何时使用何种算法。在什么情况下使用什么算法由客户端决定。
认识策略模式
策略模式的重心
策略模式的重心不是如何实现算法。而是如何组织、调用这些算法。从而让程序更灵活,具有更好的维护性和扩展性。
算法的平等性
策略模式的一个很大的特点就是各个策略算法的平等性。对于一系列具体的策略算法,大家的地位都是完全一样的,正因为这个平等性,才能实现算法之间的相互替换。所有的策略算法在实现上也是相互独立的,相互之间没有依赖。
所以可以这样描述一系列策略算法:策略算法是行为的不同实现。
运行时策略的唯一性
运行期间,策略模式的每一个时刻都只能运行一个具体的策略实现对象。虽然可以切换不同的策略实现,但同时只能使用一个。
公有的行为
经常见到的是,所有的具体策略类都有公有的行为。这时候,就应该把这些公有的行为放到公共的抽象策略角色Strategy里面。当然这个时候抽象策略角色必须用JAVA抽象类实现,而不能是接口。
这其实也是典型的代码向上继承结构的上方集中的标准做法。
策略模式的优点
(1)策略模式提供了管理相关的算法簇的办法。策略类的等级结构定义了一个算法或者行为簇,恰当的使用继承可以把公共的代码移到父类里面,从而避免代码重复。
(2)使用代码模式可以避免多重使用条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或者行为的逻辑与算法或者行为的逻辑混合在一起,统统放在一个多重语句里面,比使用继承的办法还要原始和落后。
策略模式的缺点
(1)客户端必须知道所有的策略类,并自行决定使用那一个策略类。这就意味着客户必须理解这些算法的区别,以便能适时的选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或者行为的情况。
(2)由于策略模式把每个具体的策略实现都封装成单独的类。那么当策略很多时,那么对象的数目将会相当可观的。
(本文转载自:http://www.dedecms.com/knowledge/program/jsp-java/2012/0822/12106.html)