java设计模式之策略模式
策略模式的定义:策略模式又叫政策模式,它将定义的算法族分别封装起来,让它们之间可以互相替换,从而让算法的变化不会影响到使用算法的用户,属于行为型设计模式。 很多同学可能不太理解这个定义,我举个简单的例子,比如客户要实现一个功能,分为A,B,C,D4个步骤完成,其中A和C步骤是很容易发生改变的,所以我们将A和C步骤分别封装起来, 具体实现方式是将A和C定义为接口,各自分别有1,2,3种实现方式。此时A和C对应的就是算法族,各自的实现叫做算法,各个算法之间可以相互替换,来达到不同的实现目的。客户 需要实现的功能可以由A和C算法族组合实现各式各样不同的功能,而我们实现功能的主干永远不会改变。 策略模式的使用就是面向对象的继承和多肽机制,从而实现同一行为在不同场景下具备不同的功能实现。 策略模式的UML类图:
? ? ?由上图可以看到,策略模式主要包含3个角色。
注意:策略模式中的上下文角色(Context),其职责是隔离客户端与策略类的耦合,让客户端完全与上下文角色沟通,不需要关心具体策略。 Context类在具体的开发中实现可以有多种方法,比如接下来的实例中就是通过枚举类是实现的。 策略模式实现场景:这里举一个简单的小例子,比如某明显开一场演唱会,后台调音师需要根据明星演唱的歌曲准备背景音乐。这里就可以运用策略模式去实现。 1,先定义一个背景音乐的接口,创建一个播放的方法。 package strategy;
/**
* @ClassName BackgroundMusic
* @Description 背景音乐接口
* @Author liuyi
* @Date 2020/6/14 11:08
* @Version 1.0
*/
public interface BackgroundMusic {
/**
* @Author liuyi
* @Description 定义播放的方法
* @Date 11:10 2020/6/14
* @Param []
* @return void
**/
public void play();
}
2,分别有三种背景音乐去实现该接口 背景音乐1 package strategy;
/**
* @ClassName BackgroundMusic1
* @Description TODO
* @Author liuyi
* @Date 2020/6/14 11:12
* @Version 1.0
*/
public class BackgroundMusic1 implements BackgroundMusic {
@Override
public void play() {
System.out.println("开始播放背景音乐1");
}
}
背景音乐2 package strategy;
/**
* @ClassName BackgroundMusic2
* @Description TODO
* @Author liuyi
* @Date 2020/6/14 11:13
* @Version 1.0
*/
public class BackgroundMusic2 implements BackgroundMusic{
@Override
public void play() {
System.out.println("开始播放背景音乐2");
}
}
背景音乐3 package strategy;
/**
* @ClassName BackgroundMusic3
* @Description TODO
* @Author liuyi
* @Date 2020/6/14 11:13
* @Version 1.0
*/
public class BackgroundMusic3 implements BackgroundMusic {
@Override
public void play() {
System.out.println("开始播放背景音乐3");
}
}
3,创建背景音乐编号枚举类 package strategy;
/**
* @ClassName MusicNumEnum
* @Description 背景音乐编号枚举类
* @Author liuyi
* @Date 2020/6/14 11:20
* @Version 1.0
*/
public enum MusicNumEnum {
music1(1,"strategy.BackgroundMusic1"),music2(2,"strategy.BackgroundMusic2"),music3(3,"strategy.BackgroundMusic3");
MusicNumEnum(int num,String className){
this.num = num;
this.className = className;
}
//编号
private int num;
//类名称
private String className;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
//根据num获取className
public static String getClassNameByNum(int num){
MusicNumEnum[] values = MusicNumEnum.values();
for (MusicNumEnum value : values) {
if(value.getNum()==num){
return value.getClassName();
}
}
return null;
}
}
4,测试 package strategy;
/**
* @ClassName StrategyTest
* @Description 策略模式测试类
* @Author liuyi
* @Date 2020/6/14 11:16
* @Version 1.0
*/
public class StrategyTest {
public static void main(String[] args) throws Exception {
palyByNum(1);
palyByNum(3);
palyByNum(2);
}
/**
* @Author liuyi
* @Description 根据播放编号播放对应的背景音乐
* @Date 11:41 2020/6/14
* @Param [num]
* @return void
**/
public static void palyByNum(int num) throws Exception{
//根据背景音乐编号播放对应的背景音乐
BackgroundMusic backgroundMusic = (BackgroundMusic)(Class.forName(MusicNumEnum.getClassNameByNum(num)).newInstance());
backgroundMusic.play();
}
}
从代码可以看出我们需要播放某个音乐,只需要传入对应的编号即可,不需要对主干代码进行修改。如果下场演唱会需要新增背景音乐,则添加一个背景音乐类,然后在枚举类配置对应的编号和类的关系即可。 从策略模式的概念来看,每一种背景音乐其实就是一种具体的算法,背景音乐1,背景音乐2,背景音乐3它们之间可以互相替换,来达到不同的目的,而使用的客户是不需要知道这些的存在的, 用户只需要传入算法 对应的编号或者类型即可。 策略模式的优点:
策略模式的缺点:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |