策略模式是对算法的包装,把使用算法的责任和算法自己分隔开,委派给不一样的对象管理。策略模式一般把一系列的算法包装到一系列的策略类里面,做为一个抽象策略类的子类。算法
做用ide
将算法的责任和自己进行解耦,使得:spa
1.算法可独立于使用外部而变化设计
2.客户端方便根据外部条件选择不一样策略来解决不一样问题orm
策略模式仅仅封装算法(包括添加 & 删除),但策略模式并不决定在什么时候使用何种算法,算法的选择由客户端来决定。对象
实例继承
背景:有一家百货公司,最近在定年度的促销活动接口
冲突:每一个节日用同一个促销活动太枯燥,没吸引力it
解决方案:针对不一样节目使用不一样促销活动进行促销class
步骤1:
定义抽象策略角色(Strategy):百货公司全部促销活动的共同接口
public abstract class Strategy { public abstract void showActivity(); }
步骤2:
定义具体策略角色(Concrete Strategy):
如下是每一个具体活动
//为春节准备的促销活动A class StrategyA extends Strategy{ @Override public void showActivity() { System.out.println("春节促销活动A"); } } //为中秋节准备的促销活动B class StrategyB extends Strategy{ @Override public void showActivity() { System.out.println("中秋节促销活动B"); } } //为圣诞节准备的促销活动C class StrategyC extends Strategy{ @Override public void showActivity { System.out.println("圣诞节促销活动C"); } }
步骤3:
定义环境角色(Context):用于链接上下文,即把促销活动推销给客户,这里能够理解为销售员
class Context_SalesMan{ private Strategy strategy;//持有抽象策略角色的引用 //生成销售员实例时告诉销售员什么节日(构造方法) //使得让销售员根据传入的参数(节日)选择促销活动(这里使用一个简单的工厂模式) public SalesMan(String festival) { switch ( festival) { case "A": //春节就使用春节促销活动 strategy = new StrategyA(); break; case "B": //中秋节就使用中秋节促销活动 strategy = new StrategyB(); break; case "C": //圣诞节就使用圣诞节促销活动 strategy = new StrategyC(); break; } }
//向客户展现促销活动 public void SalesManShow(){ strategy.showActivity(); }
public class StrategyPattern { public static void main(String[] args){ Context_SalesMan mSalesMan ; //春节来了,使用春节促销活动 System.out.println("对于春节:"); mSalesMan = new Context_SalesMan("A"); mSalesMan.SalesManShow(); //中秋节来了,使用中秋节促销活动 System.out.println("对于中秋节:"); mSalesMan = new Context_SalesMan("B"); mSalesMan.SalesManShow(); //圣诞节来了,使用圣诞节促销活动 System.out.println("对于圣诞节:"); mSalesMan = new Context_SalesMan("C"); mSalesMan.SalesManShow(); } }
运行结果:
总结
优势
策略类之间能够自由切换
因为策略类都实现同一个接口,因此使它们之间能够自由切换。
易于扩展
增长一个新的策略只须要添加一个具体的策略类便可,基本不须要改变原有的代码,符合“开闭原则“
避免使用多重条件选择语句(if else),充分体现面向对象设计思想。
缺点
客户端必须知道全部的策略类,并自行决定使用哪个策略类。
策略模式将形成产生不少策略类,能够经过使用享元模式在必定程度上减小对象的数量。
策略模式的本质:少用继承,多用组合