前言
一个月更新一片博客哈,又来坚持了~(这是第三个月啦) 最近碰巧在做策略模式的重构,刚好为写博客提供了素材,接下来为大家介绍策略模式~
策略模式的定义
策略模式:属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。
其实就是对算法(也就是我们的业务逻辑的处理)的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。
了解完定义后,我们再来看下策略模式通用类图:
根据这个图我们看到策略模式参与者:Context:上下文角色,持有一个Strategy的引用。
Strategy:抽象策略角色,这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口
ConcreteStrategy:具体策略角色,包装了相关的算法或行为,实现或继承了抽象策略角色。
这三个角色的功能职责都十分明确,对应的源码实现也十分简单,现在我们就来快速看下每个角色对应的通用源码。
有了策略模式的基本代码结构,在客户端类中使用十分简单,想要哪个策略,就产生出它的具体策略对象放入上下文对象内,然后由上下文对象执行具体策略操作即可,具体代码如下:
这就是策略模式的简单实现。
策略模式使用场景以及实例
我们经常会遇到很多的 if/else 代码块
比如有一个职场惩罚的需求,迟到罚款100元,工作睡觉罚款200元。我们现在的惩罚只有两个,当有越来越多的 惩罚手段,那我们这里的判断条件就会越来越多。造成代码块的冗余。
public class WorkPunish {
public static void main(String[] agrs){
String state ="late";
punish(state);
}
public static void punish(String state){
if ("late".equals(state)){
System.out.println("罚100");
}else if ("sleep".equals(state)){
System.out.println("罚200");
} System.out.println("警告");
}
}
这个时候策略模式就应运而生。使用策略模式可以帮助我们将每个处理逻辑封装成独立的类,客户端类需要进行哪种处理逻辑就使用对应的类,调用其封装了业务处理细节的方法即可。
接下来就是使用策略模式的demo了。
首次定义一个抽象接口,包含惩罚方法
public interface IPunish {
void exePunish();
}
接下来就是写具体的实现类,实现该抽象接口,实现类实现了抽象类的方法,将具体的逻辑在这里处理。 注意,我们在这立还继承了InitializingBean,InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。会将对象注册,接下来看注册的实现~
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
@Component
public class LatePunish implements IPunish,InitializingBean{
public void exePunish() {
System.out.println("罚100");
}
@Override
public void afterPropertiesSet() throws Exception {
PunishFactory.registerPunish("late", this);
}
}
这是一个工厂类。将所有的实现累在初始化的时候都注册到这里,存放在map中。根据客户端的需要选取对应的实现对象,来调用具体的方法。
import java.util.HashMap;
import java.util.Map;
public class PunishFactory {
private static Map<String,IPunish> punishMap = new HashMap<String,IPunish>();
private PunishFactory() {}
private static final IPunish EMPTY = new EmptyPunish();
//获取
public static IPunish getPunish(String state) {
IPunish result = punishMap.get(state);
return result == null ? EMPTY : result;
}
//将处罚对象注册到这里
public static void registerPunish(String state,IPunish o){
punishMap.put(state, o);
}
private static class EmptyPunish implements IPunish {
public void exePunish() {
// Empty class
}
}
}
接下里就是重构之后那一堆if/else的处理逻辑,只需要根据对应的状态,取到赌赢的对象,调用实现方法,完成需求
public class WorkPunish {
public static void main(String[] agrs){
String state ="late";
IPunish punish = PunishFactory.getPunish(state);
punish.exePunish();
}
}
到这里我们的实现就结束了,这就是使用策略模式的一种场景。
策略模式的优点
使用策略模式,可以在不修改原有系统的基础上更换算法或行为,可以灵活地增加新的算法或行为,提供了系统的扩展性
策略模式提供了对一类算法进行管理维护。
使用策略模式可以避免使用多重条件判断,由外部模块决定所要执行的策略类。
策略模式的缺点
客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
会产生很多策略类,使得类的项目增多。
结语
到这里,本文对策略模式的学习就此结束,当然关于策略模式的内容远不止这些,文章中举例是结合了策略模式和工厂模式,重构了代码。那么对于工厂模式大家是否理解,下期文章再见哈~