策略模式

阿飞 2021年04月26日 494次浏览

策略模式

策略模式定义了一组算法,将它们逐个封装起来,并使它们可以相互替换。策略可以让算法独立于使用它们的客户而变化。

应用

在业务场景中,我们经常需要根据不同的条件而执行不同方法,这个时候便可以为每一种条件定制一类特定的方法。

类图

img

如图所示

  • Strategy: 策略接口或者策略抽象类,并且策略执行的接口
  • ConcreateStrategyA、ConcreateStrategyB、ConcreateStrategyC:实现策略接口的具体策略类
  • Context:上下文类,持有具体策略类的实例,并负责调用相关的算法

示例

普通实现

定义接口

public interface PrintStrategy {

    boolean support(String code);

    void print(Message message);

}

实现类

public class OnePrintStrategy implements PrintStrategy {

    @Override
    public boolean support(String code) {
        return "1".equals(code);
    }

    @Override
    public void print(Message message) {
        System.out.println(message.toString());
    }
}
public class TwoPrintStrategy implements PrintStrategy{
    @Override
    public boolean support(String code) {
        return "2".equals(code);
    }

    @Override
    public void print(Message message) {
        System.out.println(message.toString());
    }
}

策略实例持有类

public class StrategyContext{

    private final List<PrintStrategy> strategies;

    public StrategyContext(){
        strategies = new ArrayList<>();
        strategies.add(new OnePrintStrategy());
        strategies.add(new TwoPrintStrategy());
    }

    public PrintStrategy getStrategy(String code){
        for(PrintStrategy printStrategy:strategies){
            if(printStrategy.support(code)){
                return printStrategy;
            }
        }
        throw new RuntimeException("unsupported code");
    }

}

测试

@Data
@AllArgsConstructor
public class Message {

    private String code;

    private String body;

}
public class Demo {
    public static void main(String[] args) {
        StrategyContext strategyContext = new StrategyContext();
        Message message = new Message("2","打印策略2");
        strategyContext.getStrategy(message.getCode()).print(message);
    }
}
Message(code=2, body=打印策略2)

Process finished with exit code 0

枚举实现

枚举

public enum PrintStrategyEnum {

    ONE("1"){
        @Override
        protected void print(Message message) {
            System.out.println("枚举类策略1 "+message.toString());
        }
    },
    TWO("2") {
        @Override
        protected void print(Message message) {
            System.out.println("枚举类策略2 "+message.toString());
        }
    };

    private final String code;

    PrintStrategyEnum(String code) {
        this.code = code;
    }


    protected abstract void print(Message message);

    public String getCode() {
        return code;
    }
}

测试

public class Demo {
    public static void main(String[] args) {
        StrategyContext strategyContext = new StrategyContext();
        Message message = new Message("2","打印策略2");
        strategyContext.getStrategy(message.getCode()).print(message);


        for(PrintStrategyEnum printStrategyEnum: PrintStrategyEnum.values()){
            if(printStrategyEnum.getCode().equals(message.getCode())){
                printStrategyEnum.print(message);
            }
        }



    }
}