Delegate 委派模式和代理模式strategy的区别?策略模式如何实现消除多层if else?(上)

简介: Delegate 委派模式和代理模式strategy的区别?策略模式如何实现消除多层if else?

委派模式


委派模式,可以精简程序逻辑,提升代码的可读性。


委派模式(Delegate Pattern)的基本作用就是负责任务的调用和分配任务。


例如:老板(Boss)给项目经理(Leader)下达任务,项目经理会根据实际情况给每个员工派发工作任务,待员工把工作任务完成之后,再由项目经理汇报工作进度和结果给老板。

1dc618a0ed9580ce8bfa6facb208c08f.png


和代理模式的区别


跟代理模式很像,可以看做是一种特殊情况下的静态代理的全权代理,但是代理模式注重过程,而委派模式注重结果。委派模式在Spring 中应用非常多,常用的DispatcherServlet 其实就是用到了委派模式。


案例


5d4c6812c8535adbb050f4ddf2e1bce8.png

public interface IEmployee {
    void doing(String command);
}


public class EmployeeA implements IEmployee {
    @Override
    public void doing(String command) {
        System.out.println("我是员工A,我现在开始干" + command + "工作");
    }
}
```java
public class EmployeeB implements IEmployee {
    @Override
    public void doing(String command) {
        System.out.println("我是员工B,我现在开始干" + command + "工作");
    }
}


public class Leader implements IEmployee {
    private Map<String, IEmployee> targets = new HashMap<>();
    public Leader() {
        targets.put("登录", new EmployeeA());
        targets.put("加密", new EmployeeB());
    }
    @Override
    public void doing(String command) {
        targets.get(command).doing(command);
    }
}


public class Boss {
    public void command(String command, Leader leader) {
        leader.doing(command);
    }
}


测试:


public class DelegateTest {
  public static void main(String[] args) {
  //客户请求(Boss)、委派者(Leader)、被被委派者(Target)
  //委派者要持有被委派者的引用
  //代理模式注重的是过程, 委派模式注重的是结果
  //策略模式注重是可扩展(外部扩展),委派模式注重内部的灵活和复用
  //委派的核心:就是分发、调度、派遣
  //委派模式:就是静态代理和策略模式一种特殊的组合
  new Boss().command("登录",new Leader());
  new Boss().command("加密", new Leader());
  }
}


46a9d80a6e05e4e3b19d57a0ee70bcdf.png


应用场景


手写一个DispatcherServlet: DispatcherServlet根据url分配到对应的controller的method方法就体现了委派模式。

66ba272a0bfc97be54a5fa679e3d5482.png


public class DispatcherServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            doDispatch(req, resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String uri = request.getRequestURI();
        String mid = request.getParameter("mid");
        if ("/getMemberById".equals(uri)) {
            new MemberController().getMemberById(mid);
        } else if ("/getOrderById".equals(uri)) {
            new OrderController().getOrderById(mid);
        } else if ("/logout".equals(uri)) {
            new SystemController().logout();
        } else {
            response.getWriter().write("404 Not Found!!");
        }
    }


public class MemberController {
    public void getMemberById(String mid){
        System.out.println(mid);
    }
}



public class OrderController {
    public void getOrderById(String mid){
    }
}
public class SystemController {
    public void logout(){
    }
}


策略模式


介绍

66ba272a0bfc97be54a5fa679e3d5482.png

策略模式(Strategy Pattern)是指定义了算法家族、分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户。

1dc618a0ed9580ce8bfa6facb208c08f.png


策略模式的应用场景

1、假如系统中有很多类,而他们的区别仅仅在于他们的行为不同。

2、一个系统需要动态地在几种算法中选择一种。

5d4c6812c8535adbb050f4ddf2e1bce8.png


案例1。


课程经常会有优惠活动,优惠策略会有很多种可能

如:领取优惠券抵扣、返现促销、拼团优惠。下面我们用代码来模拟,首先我们创建一

个促销策略的抽象PromotionStrategy


5d4c6812c8535adbb050f4ddf2e1bce8.png


public interface PromotionStrategy {
    void doPromotion();
}


/**
 * 返现活动
 * Created by HFL
 */
public class CashbackStrategy implements PromotionStrategy {
    @Override
    public void doPromotion() {
        System.out.println("返现促销,返回的金额转到支付宝账号");
    }
}


/**
 * 优惠券
 * 
 */
public class CouponStrategy implements PromotionStrategy {
    @Override
    public void doPromotion() {
        System.out.println("领取优惠券,课程的价格直接减优惠券面值抵扣");
    }
}


/**
 * 无优惠
 *
 */
public class EmptyStrategy implements PromotionStrategy {
    @Override
    public void doPromotion() {
        System.out.println("无促销活动");
    }
}


/**
 * 拼团优惠
 *
 */
public class GroupbuyStrategy implements PromotionStrategy{
    @Override
    public void doPromotion() {
        System.out.println("拼团,满20人成团,全团享受团购价");
    }
}


优惠活动


public class PromotionActivity {
    private PromotionStrategy promotionStrategy;
    public PromotionActivity(PromotionStrategy promotionStrategy) {
        this.promotionStrategy = promotionStrategy;
    }
    public void execute(){
        promotionStrategy.doPromotion();
    }
}


测试1:


public class PromotionActivityTest {
    public static void main(String[] args) {
        PromotionActivity activity618 = new PromotionActivity(new CouponStrategy());
        PromotionActivity activity1111 = new PromotionActivity(new CashbackStrategy());
        activity618.execute();
        activity1111.execute();
    }


根据前端的条件选择哪种策略方式:


 

public static void main(String[] args) {
        PromotionActivity promotionActivity = null;
        String promotionKey = "CASHBACK";
        if(StringUtils.equals(promotionKey,"COUPON")){
            promotionActivity = new PromotionActivity(new CouponStrategy());
        }else if(StringUtils.equals(promotionKey,"CASHBACK")){
            promotionActivity = new PromotionActivity(new CashbackStrategy());
        }//......
        promotionActivity.execute();
    }


从形式上看,这这个测试类根据条件,类似简单工厂。所以我们可以改成简单工厂的方法优化下:


再写个简单工厂类.用于生产策略类:


public class PromotionStrategyFactory {
    private static Map<String,PromotionStrategy> PROMOTION_STRATEGY_MAP = new HashMap<String, PromotionStrategy>();
    static {
        PROMOTION_STRATEGY_MAP.put(PromotionKey.COUPON,new CouponStrategy());
        PROMOTION_STRATEGY_MAP.put(PromotionKey.CASHBACK,new CashbackStrategy());
        PROMOTION_STRATEGY_MAP.put(PromotionKey.GROUPBUY,new GroupbuyStrategy());
    }
    private static final PromotionStrategy NON_PROMOTION = new EmptyStrategy();
    private PromotionStrategyFactory(){}
    public static PromotionStrategy getPromotionStrategy(String promotionKey){
        PromotionStrategy promotionStrategy = PROMOTION_STRATEGY_MAP.get(promotionKey);
        return promotionStrategy == null ? NON_PROMOTION : promotionStrategy;
    }
    private interface PromotionKey{
        String COUPON = "COUPON";
        String CASHBACK = "CASHBACK";
        String GROUPBUY = "GROUPBUY";
    }
}


重写测试类:


public static void main(String[] args) {
        String promotionKey = "GROUPBUY";
        PromotionActivity promotionActivity = new PromotionActivity(PromotionStrategyFactory.getPromotionStrategy(promotionKey));
        promotionActivity.execute();
    }
相关文章
|
7月前
|
设计模式
二十三种设计模式全面解析-解密组合模式(Composite Pattern):构建统一而强大的对象结构
二十三种设计模式全面解析-解密组合模式(Composite Pattern):构建统一而强大的对象结构
118 0
|
7月前
|
设计模式 Java
Java设计模式【二十二】:空对象模式
Java设计模式【二十二】:空对象模式
59 0
|
设计模式 缓存 算法
JAVA设计模式14:策略模式,使算法的变化独立于使用它的客户端
JAVA设计模式14:策略模式,使算法的变化独立于使用它的客户端
105 0
|
7月前
|
设计模式 存储 安全
二十三种设计模式全面解析-享元模式(Flyweight Pattern)详解:构建高效共享的对象结构
二十三种设计模式全面解析-享元模式(Flyweight Pattern)详解:构建高效共享的对象结构
|
5月前
|
设计模式
对抗软件复杂度问题之组合(Composite)方法设计模式是什么,如何解决
对抗软件复杂度问题之组合(Composite)方法设计模式是什么,如何解决
|
设计模式 存储 Java
JAVA设计模式11:组合模式,以统一的方式处理单个对象和组合对象
JAVA设计模式11:组合模式,以统一的方式处理单个对象和组合对象
174 0
|
设计模式 Java 数据库连接
JAVA设计模式8:装饰模式,动态地将责任附加到对象上,扩展对象的功能
JAVA设计模式8:装饰模式,动态地将责任附加到对象上,扩展对象的功能
|
设计模式 Java
空对象模式【Java设计模式】
空对象模式【Java设计模式】
57 0
|
设计模式 存储 安全
【大话设计模式】抽象 接口 集合 泛型
【大话设计模式】抽象 接口 集合 泛型
|
算法 Java 调度
Delegate 委派模式和代理模式strategy的区别?策略模式如何实现消除多层if else?(下)
Delegate 委派模式和代理模式strategy的区别?策略模式如何实现消除多层if else?(下)
143 0
Delegate 委派模式和代理模式strategy的区别?策略模式如何实现消除多层if else?(下)