前言
正文
介绍
Define a family of algorithms,encapsulate each one,and make them interchangeable.(定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。) -设计模式之禅第2版
就是将过程封装起来,以面向对象的方式使用,方便替换。策略模式的使用场景可以分为两种,一种是“静态”,在编译时就确定的,直接调用策略类就好了。还有一种是“动态”,在运行时确定,这种可以传入判断的参数来获取相应的策略类的实例。因为是生产不同类的实例,这里可以结合工厂类使用
通用类图及代码
类图
抽象出一个接口,来规整策略类格式
之后就是具体的实现类了,实现策略方式
静态的策略模式,这里就可以了,使用时直接调用用策略实现类封装好的代码就可以了
类图如下
如果是动态的,这里可以加一个静态工厂
代码
IStrategy
public interface IStrategy {public void doSomething();}
ConcreteStrategy
public class ConcreteStrategy1 implements IStrategy{
@Override
public void doSomething() {
System.out.println("HELLO WORLD");
}
}
public class ConcreteStrategy2 implements IStrategy{
@Override
public void doSomething() {
System.out.println("hello world");
}
}
Client1
如果是静态的,这里直接调用就可以了,就像这个样子
public class Client1 {
public static void main(String[] args) {
IStrategy strategy = new ConcreteStrategy1();
strategy.doSomething();
}
}
即时加载StrategyFactory
如果使用即时加载的话,在静态代码块里初始化就好了
import java.util.HashMap;
public class StrategyFactory {
private static HashMap<String,IStrategy> map = new HashMap<>();
static{
map.put("A",new ConcreteStrategy1());
map.put("B",new ConcreteStrategy2());
}
public static IStrategy getStrategy(String type){
if(type == null || type.isEmpty()){
throw new IllegalArgumentException("type should not be empty");
}
return map.get(type);
}
}
非即时加载StrategyFactory
如果策略太多,即时加载拖累速度的话,也可以使用延迟加载,这里有两种方式,一是使用选择语句,匹配对应的 type 后实例化相应的类,然后返回实例
使用选择语句
public class StrategyFactory1 {
public static IStrategy getStrategy(String type){
if(type == null || type.isEmpty()){
throw new IllegalArgumentException("type should not be empty");
}
return switch (type) {
case "A" -> new ConcreteStrategy1();
case "B" -> new ConcreteStrategy2();
default -> null;
};
}
}
使用反射
public class StrategyFactory2 {
public static <T extends IStrategy> IStrategy getStrategy(Class<T> tClass){
IStrategy strategy = null;
try{
strategy = (IStrategy) Class.forName(tClass.getName()).getConstructor().newInstance();
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
e.printStackTrace();
}
return strategy;
}
}
使用
public class Client2 {
public static void main(String[] args) {
IStrategy strategy2 = StrategyFactory2.getStrategy(ConcreteStrategy1.class);
strategy2.doSomething();
IStrategy strategy1 = StrategyFactory1.getStrategy("A");
strategy1.doSomething();
}
}
