介绍
意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
主要解决:在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。
何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。
如何解决:将这些算法封装成一个一个的类,任意地替换。
关键代码:实现同一个接口。
应用实例: 1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。 2、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。 3、JAVA AWT 中的 LayoutManager。
优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。
使用场景: 1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。 2、一个系统需要动态地在几种算法中选择一种。 3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。
日常碰到的业务概述
登录类型,支付类型,供应商渠道,不同等级会员享受的优惠券价格不一样,等等业务判断,大量if else导致拓展(侧重新增)极其困难,维护(侧重修改)自然是改起来头痛(其实一个类型的增加[拓展一个类型]往往对应这个类型的增删改查CRUD[维护]),比如业务一开始一个简单的登录,往往做一个电话号码和验证码登录的方式或者账号密码登录方式,后来随着业务的增加或者提高用户体验,那么需要拓展(新增一种)三方登录,比如新增微信登录,支付宝登录,甚至抖音登录,一大堆,你要根据登录方式来处理,那就有点恼火吧,支付方式也是同样的问题,我们可以发现一个规律,凡是可以枚举的业务,往往都需要使用设计模式才能更好的解决,比如策略模式(往往搭配工厂模式使用更配哦),水来土掩,兵来将挡,这思想和高中数学中的分类讨论思想一模一样.遇事不要慌,因为还有dang中央.所以,我们就打个栗子,举个比方,更加形象一点,
这是一个父类:
`public class Processor {
public String name(){
//获取当前类名 返回源代码中给出的底层类的简称
return getClass().getSimpleName();
}
Object process (Object input){
return input;
}
}`
接下来有三个子类继承父类:
public class Downcase extends Processor {
String process(Object input){
//转换小写
return ((String)input) .toLowerCase();
}
}
public class Splitter extends Processor{
String process(Object input){
return Arrays.toString(((String)input).split(" "));
}
}
public class Upcase extends Processor {
String process(Object input){
//转换成大写
return ( (String)input) .toUpperCase();
}
}
main调用
public class Apply {
public static void process(Processor p,Object s ){
System.out.println("Using processor"+p.name());
System.out.println(p.process(s));
}
public static String s = "Hello Word";
public static void main(String[] args) {
process(new Upcase(),s);
process(new Downcase(),s);
process(new Splitter(),s);
}
}
输出结果:
Apply.process()方法可以接受任何类型的Processor,·并将其应用到–个Object对象上,然后打印结果。
像本例这样,创建一个能够根据所传递的参数对象的不同而具有不同行为的方法,被称为策略设计模式。
这类方法包含所要执行的算法中固定不变的部分,而“策略”包含变化的部分。策略就是传递进去的参数对象,它包含要执行的代码。这里,Processor对象就是一个策略,在main)中可以看到有三种不同类型的策略应用到了String类型的s对象上。