策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。比如每个人都要“交个人所得税”,但是“在美国交个人所得税”和“在中国交个人所得税”就有不同的算税方法。
策略模式的结构组成:
—抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
—具体策略角色:包装了相关的算法和行为。
—环境角色:持有一个策略类的引用,最终给客户端调用
原理我相信大家都知道,应该如何应用呢?怎样融合到项目开发中?
使用策略模式可以很容易实现可插拔系统的设计。
策略模式实践场景(1): 普通应用场景,基于普通jar包里面的应用
1.定义抽象策略角色TargetInterface,具体策略角色:教师TeacherImpl和学生StudentImpl,环境角色PolicyManager
/**
* 抽象策略角色
*
* @author: fengyantao
* @date: 2019/11/14 上午11:31
* @version: V1.0
* @review: fengyantao/2019/11/14 上午11:31
*/
public interface TargetInterface {
//策略方法
String read();
}
/**
* 具体策略角色: 学生
*
* @author: fengyantao
* @date: 2019/11/14 上午11:32
* @version: V1.0
* @review: fengyantao/2019/11/14 上午11:32
*/
public class StudentImpl implements TargetInterface {
@Override
public String read() {
return "学生";
}
}
/**
* 具体策略角色:教师
*
* @author: fengyantao
* @date: 2019/11/14 上午11:33
* @version: V1.0
* @review: fengyantao/2019/11/14 上午11:33
*/
public class TeacherImpl implements TargetInterface {
@Override
public String read() {
return "教师";
}
}
/**
* 环境角色
*
* @author: fengyantao
* @date: 2019/11/14 上午11:39
* @version: V1.0
* @review: fengyantao/2019/11/14 上午11:39
*/
public class PolicyManager {
private TargetInterface targetInterface;
public PolicyManager(TargetInterface targetInterface) {
this.targetInterface = targetInterface;
}
public String read() {
return targetInterface.read();
}
}
2.编写测试类
/**
* 普通应用场景
*/
public static void commonTest() {
TargetInterface studentImpl = new StudentImpl();
PolicyManager policyManager = new PolicyManager(studentImpl);
TargetInterface teacherImpl = new TeacherImpl();
PolicyManager policyManager1 = new PolicyManager(teacherImpl);
System.out.println("======================" + policyManager.read());
System.out.println("======================" + policyManager1.read());
}
结果输出:
==========================学生
==========================教师
策略模式实践场景(2):基于框架的使用,比如某个接口有很多实现(100个),在某个service中需要调用10个不同的实现类,那么就需要注入10个实现类,就会看到好多@Resource(name = "serImpl")的注解。那么代码看起来就很费劲了。
笔者基于上面的类做些改变,融合到框架中。
1.每个具体策略角色添加@Service注解,把对象交给spring框架管理,创建spring框架管理者SpringContextManager,动态获取bean实例
/**
* 抽象策略角色
*
* @author: fengyantao
* @date: 2019/11/14 上午11:31
* @version: V1.0
* @review: fengyantao/2019/11/14 上午11:31
*/
public interface TargetInterface {
//策略方法
String read();
}
/**
* 具体策略角色: 学生
*
* @author: fengyantao
* @date: 2019/11/14 上午11:32
* @version: V1.0
* @review: fengyantao/2019/11/14 上午11:32
*/
@Service
public class StudentImpl implements TargetInterface {
@Override
public String read() {
return "学生";
}
}
/**
* 具体策略角色:教师
*
* @author: fengyantao
* @date: 2019/11/14 上午11:33
* @version: V1.0
* @review: fengyantao/2019/11/14 上午11:33
*/
@Service
public class TeacherImpl implements TargetInterface {
@Override
public String read() {
return "教师";
}
}
/**
* 环境角色
*
* @author: fengyantao
* @date: 2019/11/14 上午11:39
* @version: V1.0
* @review: fengyantao/2019/11/14 上午11:39
*/
public class PolicyManager {
private TargetInterface targetInterface;
public PolicyManager(TargetInterface targetInterface) {
this.targetInterface = targetInterface;
}
public String read() {
return targetInterface.read();
}
}
/**
* spring框架管理
*
* @author: fengyantao
* @date: 2019/11/14 上午11:39
* @version: V1.0
* @review: fengyantao/2019/11/14 上午11:39
*/
@Configuration
@SuppressWarnings("all")
public class SpringContextManager implements ApplicationContextAware {
private static ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext contex) throws BeansException {
applicationContext = contex;
}
public static ApplicationContext getContext() {
return applicationContext;
}
/**
* 根据类从spring上下文获取bean。
*
* @param clazz
* @param <T>
* @return
*/
public static <T> T getBean(Class<T> clazz) {
Assert.notNull(applicationContext, "SpringContextManager启动失败...");
return applicationContext.getBean(clazz);
}
/**
* 根据类名从spring上下文获取bean。
*
* @param beanId
* @param <T>
* @return
*/
public static <T> T getBean(String beanId) {
Assert.notNull(applicationContext, "SpringContextManager启动失败...");
return (T) applicationContext.getBean(beanId);
}
}
2.编写测试类
/**
* 框架应用场景
*/
public void applicationTest() {
TargetInterface studentImpl = SpringContextManager.getBean("studentImpl");
PolicyManager policyManager = new PolicyManager(studentImpl);
TargetInterface teacherImpl = SpringContextManager.getBean("teacherImpl");
PolicyManager policyManager1 = new PolicyManager(teacherImpl);
System.out.println("==========================" + policyManager.read());
System.out.println("==========================" + policyManager1.read());
}
结果输出:
==========================学生
==========================教师
到此为止就讲完了,如果有问题,欢迎留言或私信。