0%

设计模式-策略模式

定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

策略模式

解决的问题:有多种算法相似的情况下,使用 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());
}
}