设计模式(五)委派模式和策略模式

委派模式定义

委派模式(Delegate Pattern)的基本作用就是负责任务的调
度和分配任务,跟代理模式很像,可以看做是一种特殊情况下
的静态代理的全权代理,但是代理模式注重过程,而委派模式
注重结果。
属于行为型模式。
Delegate 结尾的一般都是委派,Dispatcher也是

委派模式作用

1、掌握委派模式,精简程序逻辑,提升代码的可读性。
2、通过学习策略模式来消除程序中大量的 if…else…和 switch 语句。
3、深刻理解策略模式的应用场景,提高算法的保密性和安全性。

委派模式简单例子

public interface Task
{
    void doTask(String command);
}
public class ConcreteTaskA implements Task
{
    public void doTask(String command)
    {
        System.out.println("A执行任务"+command);
    }
}
public class ConcreteTaskB implements Task
{
    public void doTask(String command)
    {
        System.out.println("B执行任务"+command);
    }
}
public class TaskDelegate implements Task
{
    private Map<String, Task> targets = new HashMap<String, Task>();

    /**
     * 项目经理持有小组成员可供选择,类似策略模式
     */
    public TaskDelegate() {
        targets.put("加密", new ConcreteTaskA());
        targets.put("登录", new ConcreteTaskB());
    }

    public void doTask(String command) {
        targets.get(command).doTask(command);
    }
}
 public static void main(String[] args) {
        new TaskDelegate().doTask("登录");
        new TaskDelegate().doTask("加密");
    }

运行结果:

B执行任务登录
A执行任务加密

委派模式对比代理模式

委派模式(Delegate Pattern)的基本作用就是
负责任务的调用和分配任务,跟代理模式很像,可以看做是一种特殊情况下的静态代理
的全权代理,但是代理模式注重过程,而委派模式注重结果

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

策略模式定义

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

策略模式的应用场景

1、假如系统中有很多类,而他们的区别仅仅在于他们的行为不同。
2、一个系统需要动态地在几种算法中选择一种。

用策略模式实现选择支付方式的业务场景

策略模式的优缺点

优点:
1、策略模式符合开闭原则。
2、避免使用多重条件转移语句,如 if…else…语句、switch 语句
3、使用策略模式可以提高算法的保密性和安全性。
缺点:
1、客户端必须知道所有的策略,并且自行决定使用哪一个策略类。
2、代码中会产生非常多策略类,增加维护难度。

委派模式与策略模式综合应用

自己手写一个DispatcherServlet

public class MemberController {

    public void getMemberById(String mid){

    }

}
package com.gupaoedu.vip.pattern.delegate.mvc;

import com.gupaoedu.vip.pattern.delegate.mvc.controllers.MemberController;
import com.gupaoedu.vip.pattern.delegate.mvc.controllers.OrderController;
import com.gupaoedu.vip.pattern.delegate.mvc.controllers.SystemController;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 相当于是项目经理的角色
 * Created by Tom.
 */
public class DispatcherServlet extends HttpServlet{

    private List<Handler> handlerMapping = new ArrayList<Handler>();

    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){

        }
    }

//    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!!");
//        }
//
//    }


    private void doDispatch(HttpServletRequest request, HttpServletResponse response){

        //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();

    }


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


    class Handler{

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

        public Object getController() {
            return controller;
        }

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

        public Method getMethod() {
            return method;
        }

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

        public String getUrl() {
            return url;
        }

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


}

jdk、Spring的策略模式

例如 Comparator接口、Spring中的InstantiationStrategy接口

策略模式和简单工厂区别

相同点:都是通过一个标识决定不同的分支代码,简单工厂是返回不同的实例,委派模式是执行一段算法,或者调用不同的方法
区别:简单工厂返回的是实例对象,策略模式调用的是算法,根据之前说的设计模式的设计类型来分,简单工厂是创造型模式,策略模式是行为型模式

简单工厂

1、有已知的产品类

2、你无法准确的知道编译哪个产品类

3、需要在运行时决定创建哪个产品类

4、产品类不多

很明显看出,简单工厂在创建对象上的灵活性高,但是工厂类只能创建可能会使用到的产品类,假如新添了产品类就得修改工厂类,这样就会违反开闭原则。

策略模式
1、某方法里有多个条件语句,条件语句代码块里有许多行为过程。

2、其算法能封装到策略类

2、算法随意切换

3、算法与客户端隔离

这样一来,通过选择对应的策略类,作为参数传到Content类里,在运行时配置对应的算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值