设计模式 策略模式strategy & 委派模式deledate

策略模式:定义一组实现相同接口的类,高层模块根据场景实例化合适的对象
委派模式:委派类持有被委派类的引用,并由委派类完成任务的分发、调度

  1. 策略模式和委派模式的实现方式是一样的: (组合)单控制类 + 执行逻辑接口,通过创建不同的执行逻辑子类,完成解耦和复用
  2. 是不同侧重下的不同描述:
    • 策略模式:侧重实现类之间可替换,(任务调度分派的职责交由高层模块)
    • 委派模式:侧重任务调度分派,(只有一个被委派对象的情况下就无需策略了)
  3. 策略模式允许高层模块决定采取哪种策略,而委派模式的委派细节对于高层模块是不可见的
    PS:一般而言,多执行者的情景中,委派模式 ≈ 工厂方法模式 + 策略模式

策略模式(strategy)

general

// 策略模式 - 一般应用中,策略模式的策略一般由高层模块决定(此和委派模式有细微不同,职责划分的区别)
public class Context{
    private IStrategy strategy = null;

    Context(IStrategy strategy){
        this.strategy = strategy;
    }

    public void algorithm(){
        strategy.algorithm();
    }
}

通过工厂方法模式对策略进行管理

public class StrategyFactory {
    private static HashMap<String, IStrategy> strategyContainer = null;

    static{
        strategyContainer = new HashMap<>();
        strategyContainer.put(StrategyType.A,new StrategyA());
        strategyContainer.put(StrategyType.B,new StrategyB());
    }

    // 现在的策略实现类存放在容器中,属于共享使用(单例)
    public IStrategy getStrategy(String stratrgyName){
        return strategyContainer.get(stratrgyName);
    }

    // 维护一份策略列表,用户根据策略常量获取对应的策略
    public static final class StrategyType{
        public static final String A = "A";
        public static final String B = "B";
    }
}

枚举策略!!!

public enum EnumStrategy {
    ADD(){
        @Override
        public int exec(int a, int b) {
            return a + b;
        }
    },
    SUB(){
        @Override
        public int exec(int a, int b) {
            return a - b;
        }
    };

    private EnumStrategy(){}

    public abstract int exec(int a, int b);
}

strategy Test

    // Test - 策略模式语境下,策略是由高层模块决定的。
    public static void main(String[] args) {
        // 普通策略模式
        Context contextA = new Context(new StrategyA());
        contextA.algorithm();

        // 策略模式与工厂模式合并使用,工厂模式负责创建策略类(工厂模式也维护了一份策略常量类)
        StrategyFactory strategyFactory = new StrategyFactory();
        IStrategy strategyB = strategyFactory.getStrategy(StrategyFactory.StrategyType.B);
        Context contextB = new Context(strategyB);
        contextB.algorithm();

        // 枚举策略
        int add = EnumStrategy.ADD.exec(1,2);  // add = 3;
    }

委派模式(deledate)

general

// 委派模式,语境中侧重委派 (根据用户输入参数,委派给不同的executor处理)
public class Delegater{
    // 初始化被委派人
    private Map<String, IExecutor> executors = null;
    {
        executors = new HashMap<>();
        executors.put("A",new ExecutorA());
        executors.put("B",new ExecutorB());
    }

    // 根据策略选择被委派者,将任务委托给被选中者执行。
    public void execute(String command) {
       if(executors.containsKey(command)){
           executors.get(command).execute(command);
       }
    }
}

spring dispatcher模拟

public class DispatcherServlet extends HttpServlet {
    // 初始化执行环境 - handlerMapping和ioc
    private static ConcurrentHashMap<String, Method> handlerMapping = new ConcurrentHashMap<>();
    private static ConcurrentHashMap<String, Object> ioc = new ConcurrentHashMap<>();

    static{
        try {
            handlerMapping.putIfAbsent("/selectAll",MemberController.class.getMethod("selectAll"));
            ioc.putIfAbsent("/selectAll",new MemberController());
        } catch (NoSuchMethodException e){
            e.printStackTrace();
        }
    }

    @Override
    public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doDispatch(req.getRequestURI());   // 已简化
    }

    public void doDispatch(String uri){
        try {
            // method.invoke(Object,params[]) - 委派Object执行method. 
            Method method = handlerMapping.get(uri);
            method.invoke(ioc.get(uri),null);
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

strategy Test

// 委派模式语境下,用户只知Delegater完成了对应任务(不知具体的委派流程和实现)
public class Test {
    public static void main(String[] args) {
        Delegater delegater = new Delegater();
        delegater.execute("A");
        delegater.execute("B");

        DispatcherServlet dispatcherServlet = new DispatcherServlet();
        dispatcherServlet.doDispatch("/selectAll");
    }
}
原文地址:https://www.cnblogs.com/kiqi/p/14032586.html