委派模式和策略模式

一、委派模式

1.1、定义

委派模式不属于GOF23中设计模式中。委派模式的基本作用就是负责任务的调用和分配任务,和代理模式很像,可以看做是一种特殊情况下的静态代理的全权代理,但是代理模式注重过程,二委派模式注重结果。spring中DispatcherServlet其实就是委派模式。
在这里插入图片描述

1.2、实例

老板boos给项目经理leader下达任务,项目经理会根据实际情况给每个员工派发任务,待员工把工资任务完成之后,再由项目经理汇报工资进度和结果给老板。

Iemployee员工接口

/**
 * <p>
 *     委派模式
 *     员工接口
 * </p>
 *
 * @author: longWarren
 * @time: 2020/08/31
 */
public interface IEmployee {

    public void doing(String command);

}

A类员工

/**
 * <p>
 *     委派模式:A类员工
 * </p>
 *
 * @author: longWarren
 * @time: 2020/08/31
 */
public class EmployeeA implements IEmployee{

    @Override
    public void doing(String command) {
        System.out.println("我是员工A,我现在开始干" + command + "工作");
    }

}

B类员工

/**
 * <p>
 *      委派模式:A类员工
 * </p>
 *
 * @author: longWarren
 * @time: 2020/08/31
 */
public class EmployeeB implements IEmployee{

    @Override
    public void doing(String command) {
        System.out.println("我是员工B,我现在开始干" + command + "工作");
    }
    
}

项目经理leader

/**
 * <p>
 *     委派模式:领导,员工的领导
 * </p>
 *
 * @author: longWarren
 * @time: 2020/08/31
 */
public class Leader implements IEmployee{

    private Map<String,IEmployee> targets = new HashMap<String, IEmployee>();

    public Leader(){
        targets.put("加密",new EmployeeA());
        targets.put("登录",new EmployeeB());
    }

    //项目经理自己不干活
    @Override
    public void doing(String command) {
        targets.get(command).doing(command);
    }
}

老板boss

/**
 * <p>
 *     委派模式:老板
 * </p>
 *
 * @author: longWarren
 * @time: 2020/08/31
 */
public class Boss {

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

test

/**
 * <p>
 *     委派模式
 * </p>
 *
 * @author: longWarren
 * @time: 2020/08/31
 */
public class DelegateTest {

    public static void main(String[] args) {

        //客户请求(Boss)、委派者(Leader)、被被委派者(Target)
        //委派者要持有被委派者的引用
        //代理模式注重的是过程, 委派模式注重的是结果
        //策略模式注重是可扩展(外部扩展),委派模式注重内部的灵活和复用
        //委派的核心:就是分发、调度、派遣

        //委派模式:就是静态代理和策略模式一种特殊的组合

        new Boss().command("登录",new Leader());
    }

}

SpringMvc中的DispatcherServlet
委派模式和策略模式的综合应用模拟
其中还包含单例模式,工厂模式

/**
 * <p>
 *     模拟SpringMvc的DispatcherServlet
 * </p>
 *
 * @author: longWarren
 * @time: 2020/08/31
 */
public class SimulationDispatcherServlet extends HttpServlet {

    /**
     * <servlet>
     *  <servlet-name>delegateServlet</servlet-name>
     *  <servlet-class>com.gupaoedu.vip.pattern.delegate.mvc.DispatcherServlet</servlet-class>
     *  <load-on-startup>1</load-on-startup>
     * </servlet>
     *
     * <servlet-mapping>
     *  <servlet-name>delegateServlet</servlet-name>
     *  <url-pattern>/*</url-pattern>
     * </servlet-mapping>
     */

    //委派模式和策略模式的综合应用
    private List<Handler> handlerMapping= new ArrayList<Handler>();

    @Override
    public void init() throws ServletException {
        try {
            /*Class<?> memberControllerClass = MemberController.class;
            handlerMapping.add(new Handler()
                    .setController(memberControllerClass.newInstance())
                    .setMethod(memberControllerClass.getMethod("getMemberById", new
                            Class[]{String.class}))
                    .setUrl("/web/getMemberById.json"));*/
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception{
        //1、获取用户请求的url
        // 如果按照J2EE 的标准、每个url 对对应一个Serlvet,url 由浏览器输入
                String uri = request.getRequestURI();
        //2、Servlet 拿到url 以后,要做权衡(要做判断,要做选择)
        // 根据用户请求的URL,去找到这个url 对应的某一个java 类的方法
        //3、通过拿到的URL 去handlerMapping(我们把它认为是策略常量)
        Handler handle = null;
        for (Handler h: handlerMapping) {
            if(uri.equals(h.getUrl())){
                handle = h;
                break;
            }
        }
        //4、将具体的任务分发给Method(通过反射去调用其对应的方法)
        Object object = null;
        try {
            object =
                    handle.getMethod().invoke(handle.getController(),request.getParameter("mid"));
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        //5、获取到Method 执行的结果,通过Response 返回出去
        // response.getWriter().write();
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            doDispatch(req,resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static class Handler{

        private Object controller;
        private Method method;
        private String url;

        public Object getController() {
            return controller;
        }

        public void setController(Object controller) {
            this.controller = controller;
        }

        public Method getMethod() {
            return method;
        }

        public void setMethod(Method method) {
            this.method = method;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }
    }
}

二、策略模式

2.1、定义

策略模式是指定义了算法加载、分别封装起来,让他们自己可以互相替换,此模式让算法的变化不会影响到使用算法的用户。

2.2、应用场景

加入系统中有很多类,而他们的区别仅仅在于他们的行为不同
一个系统需要动态的在几种算法中选择一种

2.3、实例

促销策略

促销策略接口或抽象

/**
 * <p>
 *     促销策略抽象
 * </p>
 *
 * @author: longWarren
 * @time: 2020/08/31
 */
public interface IPromotionStrategy {
    void doPromotion();
}

促销策略之无优惠

/**
 * <p>
 *    无优惠
 * </p>
 *
 * @author: longWarren
 * @time: 2020/08/31
 */
public class EmptyStrategyI implements IPromotionStrategy {

    @Override
    public void doPromotion() {
        System.out.println("无促销活动");
    }
}

促销策略之优惠券抵扣策略

/**
 * <p>
 *    优惠券抵扣策略
 * </p>
 *
 * @author: longWarren
 * @time: 2020/08/31
 */
public class CouponStrategyI implements IPromotionStrategy {

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

促销策略之返现活动

/**
 * <p>
 *    返现活动
 * </p>
 *
 * @author: longWarren
 * @time: 2020/08/31
 */
public class CashBackStrategyI implements IPromotionStrategy {

    @Override
    public void doPromotion() {
        System.out.println("返现促销,返回的金额转到支付宝账号");
    }
}

促销策略之拼团优惠策略

/**
 * <p>
 *    拼团优惠策略
 * </p>
 *
 * @author: longWarren
 * @time: 2020/08/31
 */
public class GroupBuyStrategyI implements IPromotionStrategy {

    @Override
    public void doPromotion() {
        System.out.println("拼团,满20 人成团,全团享受团购价");
    }
}

优惠活动类,相当于代理类,内部实现对外隐藏,再来一个无参的方法(默认策略)就完美了

/**
 * <p>
 *     优惠活动
 * </p>
 *
 * @author: longWarren
 * @time: 2020/08/31
 */
public class PromotionActivity {

    private IPromotionStrategy IPromotionStrategy;

    public PromotionActivity(IPromotionStrategy IPromotionStrategy) {
        this.IPromotionStrategy = IPromotionStrategy;
    }

    public void execute(){
        IPromotionStrategy.doPromotion();
    }
}

促销策略工厂,简化使用难度,隐藏内部实现

/**
 * <p>
 *     促销策略工厂
 * </p>
 *
 * @author: longWarren
 * @time: 2020/08/31
 */
public class PromotionStrategyFactory {

    private static Map<String, IPromotionStrategy> PROMOTION_STRATEGY_MAP = new HashMap<String,
            IPromotionStrategy>();
    static {
        PROMOTION_STRATEGY_MAP.put(PromotionKey.COUPON,new CouponStrategyI());
        PROMOTION_STRATEGY_MAP.put(PromotionKey.CASHBACK,new CashBackStrategyI());
        PROMOTION_STRATEGY_MAP.put(PromotionKey.GROUPBUY,new GroupBuyStrategyI());
    }

    private static final IPromotionStrategy NON_PROMOTION = new EmptyStrategyI();

    private PromotionStrategyFactory(){}

    public static IPromotionStrategy getPromotionStrategy(String promotionKey){
        IPromotionStrategy IPromotionStrategy = PROMOTION_STRATEGY_MAP.get(promotionKey);
        return IPromotionStrategy == null ? NON_PROMOTION : IPromotionStrategy;
    }

    private interface PromotionKey{
        String COUPON = "COUPON";
        String CASHBACK = "CASHBACK";
        String GROUPBUY = "GROUPBUY";
    }
}

策略模式测试类

/**
 * <p>
 *     策略模式测试类
 * </p>
 *
 * @author: longWarren
 * @time: 2020/08/31
 */
public class StrategyTest {

    public static void main(String[] args) {
        String promotionKey = "GROUPBUY";
        PromotionActivity promotionActivity = new
                PromotionActivity(PromotionStrategyFactory.getPromotionStrategy(promotionKey));
        promotionActivity.execute();
    }
}

这个策略模式是说,要促销,但怎促销并不知道,PromotionActivity是促销的入口,但是怎么促销是个问题,需要提供促销类或者通过别的方式指定促销类

2.4策略模式在JDK中的应用
Comparator就是策略模式,比较器是一个策略,实现Comparator接口就可以,但是要比较策略却是未知的,需要客户提供或者指明。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内容简介: 设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 本课程内容定位学习设计原则,学习设计模式的基础。在实际开发过程中,并不是一定要求所有代码都遵循设计原则,我们要考虑人力、时间、成本、质量,不是刻意追求完美,要在适当的场景遵循设计原则,体现的是一种平衡取舍,帮助我们设计出更加优雅的代码结构。本章将详细介绍开闭原则(OCP)、依赖倒置原则(DIP)、单一职责原则(SRP)、接口隔离原则(ISP)、迪米特法则(LoD)、里氏替换原则(LSP)、合成复用原则(CARP)的具体内容。 为什么需要学习这门课程? 你在日常的开发中,会不会也遇到过同样的问题。系统出现问题,不知道问题究竟出在什么位置;当遇到产品需求,总是对代码缝缝补补,不能很快的去解决。而且平时工作中,总喜欢把代码堆在一起,出现问题时,不知道如何下手,工作效率很低,而且自己的能力也得不到提升。而这些都源于一个问题,那就是软件设计没做好。这门课能帮助你很好的认识设计模式,让你的能力得到提升。课程大纲: 为了让大家快速系统了解设计模式知识全貌,我为您总结了思维导图,帮您梳理学习重点,建议收藏!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值