hello,大家好,今天是星期五,明天就要周末啦,大家放松一下吧,小慕也得放松下,但是今天还是得学习的呀,今天给大家分享的内容是“策略模式”。如标题所说,学不会的话,我请你下馆子好吧
一、啥是策略模式?
策略模式(Strategy Pattern):定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化,也称为政策模式(Policy)。
二、策略模式的适用场景:
-
当一个应用程序需要实现一种特定的服务或者功能,而且该程序有多种实现方式时使用。
-
算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
-
一个类定义了多种行为 , 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。(ps:说白了就是当代码里出现太多的if else,且这些条件操作很类似的时候就可以考虑使用“策略模式”)
当然了,策略模式的主要目的并不是为了避免if-else,而是为了遵循程序的开闭原则。(ps:说白了就是避免你一直在代码后面加if else,每次新增加一种处理情况,你都得加if else,那就不符合开闭原则)所谓开闭原则,也就是说:对扩展是开放的,对修改是关闭的。运行程序的扩展,但是不允许修改原有的程序策略行为。
三、策略模式入门应用
策略模式的重心不是如何来实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活、具有更好的维护性和扩展性。
首先我们来看一下策略模式的组成:
1、抽象策略角色:通常有一个接口或一个抽象类实现
2、具体策略角色:包装了相关的算法和行为
3、环境角色:持有一个策略类的应用,最终供客户端调用
举个栗子吧,刘备要到江东娶老婆了,走之前诸葛亮给赵云三个锦囊妙计,说是遇到危险情况时,可以分别打开。
三个要素:三个妙计(具体策略类)、一个锦囊(环境类)、赵云(调用者)。
抽象策略类( AbstractStrategy)
public interface AbstractStrategy {
public void operate();
}
三个具体实现类( ConcreteStrategy ):
妙计一:初到吴国
public class PlanOne implements AbstractStrategy {
@Override
public void operate() {
System.out.println("找乔国老帮忙,让吴国太给孙权施加压力,使孙权不能杀刘备");
}
}
妙计二:求吴国太放行
public class PlanTwo implements AbstractStrategy {
@Override
public void operate() {
System.out.println("用谎言(曹操打荆州)骗泡在温柔乡里的刘备回去。");
}
}
妙计三:孙夫人断后,挡住追兵
public class PlanThree implements AbstractStrategy {
@Override
public void operate() {
System.out.println("让孙夫人摆平东吴的追兵,她是孙权妹妹,东吴将领惧她三分。");
}
}
环境类( Context)
public class Context {
private Strategy strategy;
//构造函数,看你使用哪个妙计
public Context(Strategy strategy){
this.strategy = strategy;
}
public void setStrategy(Strategy strategy){
this.strategy = strategy;
}
public void operate(){
this.strategy.operate();
}
}
下面就是使用的情况了
public class Zhaoyun {
public static void main(String[] args) {
Context context;
System.out.println("----------刚到吴国使用第一个锦囊---------------");
context = new Context(new PlanOne());
context.operate();
System.out.println("\n");
System.out.println("----------刘备乐不思蜀使用第二个锦囊---------------");
context.setStrategy(new PlanTwo());
context.operate();
System.out.println("\n");
System.out.println("----------孙权的追兵来了,使用第三个锦囊---------------");
context.setStrategy(new PlanThree());
context.operate();
System.out.println("\n");
}
}
PS:就这三招,搞得的周郎是“赔了夫人又折兵”呀!这就是策略模式,高内聚低耦合的特点也表现出来了,还有一个就是扩展性,策略类可以继续添加下去,增加第4个,第5个锦囊,哈哈
四、策略模式的优缺点
优点:
-
策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免重复的代码。
-
可扩展性强,开闭原则
-
可以减少代码中的很多if else,毕竟if else是属于硬编码,不易维护
-
提供了一种算法的复用机制,由于将算法单独提取出来封装在策略类中,因此不同的环境类可以方便地复用这些策略类。
-
不希望客户端知道复杂的、与算法相关的数据结构,在具体策略类中封装算法与相关的数据结构,可以提高算法的保密性与安全性。(PS:说实话,这个地方小慕也没有搞明白,毕竟客户端调用者都能自行选择使用哪一个策略类了,那他鼠标点进这个类里去看源代码不就行了,还谈什么保密性和安全性呢???对吧!!!)
缺点:
-
客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法。换句话来说,策略模式只适用于客户端知道所有的算法或行为的情况。
-
策略模式将造成系统产生很多具体策略类,任何细小的变化都将导致系统要增加一个新的具体策略类(PS:有多少种if else情况,就得创建多少个具体策略类),可能出现策略膨胀过多的问题。
-
无法同时在客户端使用多个策略类,也就是说,在使用策略模式时,客户端每次只能使用一个策略类,不支持使用一个策略类完成部分功能后再使用另一个策略类来完成剩余功能的情况。(PS::举个例子,如果把出行方式作为一个策略结构,用户可以选择打的,也可以选择坐公交,但是不能一段路打的,一段路坐公交。)
好啦,今天的内容到这里就结束了,行百里者半九十,请不要半途而废,好吗?
历史推文