1.策略模式解决了哪些问题
我们想想,在平常的代码中,如果有不同的场景要怎么做,这时候有的同学就要说了:每个不同的场景都搞一个类型,只要在不同的场景中进来把我们的类型传进来,然后根据类型去做 if else 判断不就好了吗。当然这位同学的说法没有问题!但是我们思考一下,如果我们以后每有一个不同的场景,那我们就要加一个类型,然后再去代码里面加一个if else,如果场景多了,那代码里面满满的都是if和else if,时间长了,不但代码不利于观看,而且还不利于维护。
那么有的同学又要问了:“哎呀,既然这么麻烦,那么有没有一劳永逸的办法呢”。 那么回答你,有,策略模式就是应对这种场景的。
2.适用场景
在一件事情,有不同的解决方式,而且每一种不同的解决方式都适用于一个不同的场景。比如在上班的时候摸鱼,咱们是躺着摸鱼、还是坐着摸鱼、蹲坑摸鱼, 这些每一种不同的方式都是一种策略。
3.如何使用
ps:策略模式实现方式有很多,我这里只是其中的一种方式。
在项目中使用:
我们把摸鱼定义成一个抽象接口:
public abstract class AbstractSlackOff{
// 然后我们定义一个给外面调用的方法
public Object handle(){
return this.process();
}
// 接着定义一个抽象方法,这个方法主要来处理逻辑
protected abstract Object process();
// 如果逻辑简单切可以共用的,写在抽象类的default接口中,共用同一个,在Java8中,抽象类可以定义一个 default的接口来处理逻辑
Default aDefault(){
return null;
}
}
然后我们定义一个躺着摸鱼的类,并且我们继承上面的抽象类
// 把这个类注入到容器里面
@Component
public class LieSlackOff extends AbstractSlackOff{
@Override
protected abstract Object process(){
return "躺着摸鱼";
};
}
再定义一个坐着摸鱼的类,也继承我们的抽象类
// 把这个类注入到容器里面
@Component
public class SittingSlackOff extends AbstractSlackOff{
@Override
protected abstract Object process(){
return "坐着摸鱼";
};
}
这个时候我们可以定义一个枚举类
public enum SlackOffEnum {
/**
* 坐着摸鱼
*/
SITTING_SLACK_OFF("sittingSlackOff"),
/**
* 站着摸鱼
*/
LIE_SLACK_OFF("lieSlackOff");
private String interfaceName;
public static String getName(String SlackOffEnumToString) {
for (SlackOffEnum value : SlackOffEnum.values()) {
if (value.toString().equals(SlackOffEnumToString)){
return value.interfaceName;
}
}
return null;
}
SlackOffEnum(String interfaceName) {
this.interfaceName = interfaceName;
}
}
准备工作都做好了,接下来开始写主逻辑方法,照常定义一个类
@RestController
@RequestMapping("/v1")
public class Main{
// 构建时会将参数构建为 类名为Key,类为value
@Resource
private Map<String,AbstractSlackOff> abstractSlackOffMap;
@RequestMapping("/test")
public Object test(SlackOffEnum SoEnum){
// 通过枚举的toString()方法拿到相应的name,也就是方法实现类
String key = SlackOffEnum.getName(soEnum.toString);
// 然后在map中把相应的类取出
AbstractSlackOff abstraceSlackOff = abstractSlackOffMap.get(Key);
if(abstraceSlackOff == null) return null;
// 然后调用不同的方法处理不同的场景
Object o = abstraceSlackOff.handle();
return o;
}
}
总结: 这样就会方便很多,等我们再有 玩手机摸鱼, 吃零食摸鱼的时候,我们只需要新增一个枚举的类型,然后实现我们的抽象类,在自己的实现类中写关于自己的逻辑,可扩展性就会变得很高,不用再去修改到本来的代码。也就是我们所说的开闭原则,对扩展开放,对修改关闭。
需注意: 如果场景很少的情况下,可以不必使用设计模式,这样只会对项目造成类变多,显得整个项目变得臃肿且不易维护,需要自己考虑到自己的场景,再去使用合适的设计模式。