定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
策略模式
解决的问题:有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。
如何解决:将这些算法封装成一个一个的类,使用反射+map替换。
优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。
if-else解决多个算法相似的代码逻辑时,为什么带来了复杂性?
if-else在逻辑上是有顺序的,而多个算法相似的代码逻辑上是平行的。平行的代码逻辑使用if-else结构是复杂化了的,阅读上不好理解,扩展性差。
1
| 例子:spring源码中为实例bean注入属性值时需要判断属性值的类型,下边实例是对判断过程的优化
|
Implementation
对targetType进行if-else判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| //准备环境 TypedStringValue typedStringValue = new TypedStringValue("18"); typedStringValue.setTargetType(Integer.class);
//获取bean的属性值stringValue和属性值类型targetType String stringValue = typedStringValue.getValue(); Class<?> targetType = typedStringValue.getTargetType();
//根据targetType要转换的value Object valueToUse = null;
if (targetType == Integer.class) { //进行转换 valueToUse = Integer.parseInt(stringValue); } else if (targetType == String.class) { //进行转换 valueToUse = stringValue; }
|
优化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| /** * Description:bean的属性值和属性值类型 * * @author hxr * @version 1.0 */ public class TypedStringValue { private String value;
private Class<?> targetType;
public TypedStringValue(String value) { this.value = value; }
public String getValue() { return value; }
public void setValue(String value) { this.value = value; }
public Class<?> getTargetType() { return targetType; }
public void setTargetType(Class<?> targetType) { this.targetType = targetType; } }
|
**
* Description:策略的接口类
*
* @author hxr
* @version 1.0
*/
public interface Strategy {
/**
* Description: 判断propertype标签中的value标签的Class类型,转换value的值为Class类型
* @author: hxr
* @param:
* @return:
*/
Object exchageType(String stringValue);
}
1 2 3 4 5 6 7 8 9 10 11 12
| /** * Description:整型类型策略类 * * @author hxr * @version 1.0 */ public class IntegerTypeStrategy implements Strategy { @Override public Object exchageType(String stringValue) { return Integer.parseInt(stringValue); } }
|
1 2 3 4 5 6 7 8 9 10 11 12
| /** * Description:浮点类型策略类 * * @author hxr * @version 1.0 */ public class FloatTypeStrategy implements Strategy{ @Override public Object exchageType(String stringValue) { return Float.parseFloat(stringValue); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| /** * Description:向实例注入属性值,需要考虑属性值的类型 * * @author hxr * @version 1.0 */ public class AbstractAutowiredCapableBeanFactory { // 策略类集合 private Map<Class<?>, Class<?>> map;
public void initMap(){ map = new HashMap<>(); // 将策略类放入集合map中 map.put(Integer.class, IntegerTypeStrategy.class); map.put(Float.class, FloatTypeStrategy.class); }
// 获取要使用的策略类 public Class<?> getbean(Class<?> targetType) { return map.get(targetType); }
//生成实例工具类 public Object creatObject(Class<?> object) { try { Constructor<?> constructor = object.getConstructor(); return constructor.newInstance(); } catch (Exception e) { e.printStackTrace(); } return null; }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| /** * Description: 策略模式+反射+map策略类集合优化if-else判断 * 将stringValue转化为TypedStringValue.targetType的类型 * 优化if-else判断targetType * * @author hxr * @version 1.0 */ public class Main { public static void main(String[] args) {
// 准备环境 TypedStringValue typedStringValue = new TypedStringValue("18"); typedStringValue.setTargetType(Integer.class);
// 获取类型 Class<?> targetType = typedStringValue.getTargetType(); String stringValue = typedStringValue.getValue();
// 创建beanFactory AbstractAutowiredCapableBeanFactory beanFactory = new AbstractAutowiredCapableBeanFactory(); // 初始化策略类 beanFactory.initMap(); // 通过targetTypemap 从策略类集合map获取需要执行的策略类。 Class<?> Object = beanFactory.getbean(targetType); // 获取策略类实例 Strategy strategy = (Strategy)beanFactory.creatObject(Object);
// 执行策略类转换方法 将stringValue转化为Integer、Float、Double等类型 Object o1 = strategy.exchageType(stringValue); System.out.println(o1.getClass().getName()); } }
|