策略模式
一、定义
策略模式(Strategypattern):定义一系列算法,将每一个算法封装起来工并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化。策略模式也称为政策模式,是一种对象行为型模式。
策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理。策略模式通常把一个系列的算法封装到一系列的策略类里面作为一个抽象策略类的子类。用一句话来说,就是“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。
二、特点
模式分析:
策略模式中,由客户端自己决定在什么情况下使用什么具体策略角色。策略模式仅仅封装算法,提供新算法插入到已有系统中,以及老算法从系统中“退休”的方便,策略模式并不决定在何时使用何种算法,算法的选择由客户端来决定。这在一定程度上提高了系统的灵活性,但是客户端需要理解所有具体策略类之间的区别,以便选择合适的算法,这也是策略模式的缺点之一,在一定程度上增加了客户端的使用难度。
优点:
- 算法可以自由切换;
- 避免使用多重条件判断;
- 扩展性良好。
缺点:
- 策略类会增多;
- 所有策略类都需要对外暴露
三、使用场景
- 当一个系统中有许多类,希望动态地让一个对象在许多行为中选择一种行为时;
- 当一个系统需要动态地在几种算法中选择一种时;
- 当一个对象有很多的行为,不想使用多重的条件选择语句来选择使用哪个行为时;
四、类图
五、实战代码
厨师用不同刀片切水果的场景:
【ICutFruit.java】
package policy;
public interface ICutFruit {
public void CutStrategy(String fruitname);
}
【HoriBlade.java】
package policy;
//横切刀片
public class HoriBlade implements ICutFruit {
public void CutStrategy(String fruitname) {
System.out.println(fruitname+"一次被切成几个横片");
}
}
【MultiBlade.java】
package policy;
//多锋刀片
public class MultiBlade implements ICutFruit {
public void CutStrategy(String fruitname) {
System.out.println(fruitname+"一次被切成八瓣儿");
}
}
【FruitKnife.java】
package policy;
//小刀
public class FruitKnife implements ICutFruit {
public void CutStrategy(String fruitname) {
System.out.println(fruitname+"一次被切成一片");
}
}
【Chef.java】
package policy;
public class Chef {
private ICutFruit cutmethod;
public void SetCutMethod(ICutFruit cutmethod){
this.cutmethod=cutmethod;
}
public void CutFruit(String fruitname){
cutmethod.CutStrategy(fruitname);
}
}
【ClientClass.java】
package policy;
public class ClientClass {
public static void main(String[] args) {
Chef chef=new Chef();
ICutFruit cut=new HoriBlade();
chef.SetCutMethod(cut);
chef.CutFruit("苹果");
}
}
【运行截图】
六、策略模式与状态模式区别:
可以通过环境类状态的个数来决定是使用策略模式还是状态模式。
策略模式的环境类自己选择一个 具体策略类,具体策略类无须关心环境类;而状态模式的环境类由于外在因素需要放进一个 具体状态中,以便通过其方法实现状态的切换,因此环境类和状态类之间存在一种双向的关联关系。
区别:
用户使用策略模式时客户端需要知道所选的具体策略是哪一个,而使用状态模式时,客户端无须关心具体状态,环境类的状态会根据用户的操作自动转换。
1.如果系统中某个类的对象存在多种状态,不同状态下行为有差异,而且这些状态之间可以发生转换时使用状态模式;
2.如果系统中某个类的某一行为存在多种实现方式,用户很清楚这些差异,而且这些实现方式可以互换时使用策略模式;
喜欢的话记得点赞收藏哟😊
Java设计模式—博文专栏持续更新!