委派者模式的使用

2020-06-02 10:22:46 浏览数 (2)

前言

在线客服项目算是告一段落了,从结果来看是没有达到自己一开始设想,因为一开始想好的设计,没能完全去实现。于是在平衡反思和甩锅的心态后,抛出原因:能力有限,时间有限,关联的业务无限。

此外就是这次开发虽然是基于1.0版本的升级,但是上线的时候, 发现不仅没填上之前的坑,还挖了新坑(线上出现业务逻辑丢失以及没完全兼容已上线的衍生的功能),于是在上线之后的发布日进行优化修复。

在各种不足中,也还是有一些收获的,比如锁粒度的优化,分级锁的使用,会话的公平分配,注解校验接口参数,MySQL查询优化等等, 但是今天要聊的是在项目中使用的一种设计模式:委派者模式。

在很久之前自己也整理了23种设计模式(18年的时候写的,现在仍然放在公众号里面,好坏就不说了),但是在日常开发中,设计模式还是很少结合实际去运用, 自己熟悉且常用的设计模式无非就是单例,策略,代理这三种。23种设计模式分为创建型模式,结构型模式和行为型模式,我们要说的委派者模式并不在23种设计模式中,它的功能核心是任务的调用和分配任务, 这种模式中主要包含了三种角色: 抽象任务角色, 委派者角色, 具体任务角色。

我们熟知具体的应用: Spring MVC 中的 DispatcherServlet 根据 handlerMapping 转发具体执行逻辑到 Controller就是使用委派者模式

下面来谈一谈这种设计模式的使用。

正文

在线客服系统中,有一些常规动作:转交,挂起,分配,关闭。这些名词,我想都不难理解,因为我们打10086的人工客服可能都会听过。这些动作对于服务端而言就是不同的请求,服务端开发人员会为每一种动作的请求开发接口,每个接口调用不同的方法来执行不同的操作,就像下面 这样,对于每一种请求去调用不同的方法:

代码语言:javascript复制
public class  Test{

    @Autowired
    private ChatService service;

    @RequestMapping("close")
    public void close(){
    service.close();
    }
    
    @RequestMapping("distribute")
    public void distribute(){
    service.distribute();
    }
}

但是这些动作需要使用的方法我们可以不需要去关注, 我们只需要知道需要的动作,具体谁去做,我们可以找到一个中间人(委派者,或者中介)让他去找相应的方法去执行就行。

那么如何设计?

第一步

我们首先对任务动作进行抽象:Execute接口。然后将具体的任务角色(执行的方法)进行实现, 比如负责转交的角色叫做Transfer,负责关闭的角色叫做Close,负责分配的角色叫做Distribute,他们都实现Execute接口。

代码语言:javascript复制
public interface Execute {
    void execute(GroupChatInfoDo groupChatInfoDo);
}

//分配
public class Distribute implements Execute {
    @Override
    public void execute(GroupChatInfoDo groupChatInfoDo) {
        System.out.println("分配动作");
    }
}

//转交
public class Transfer implements Execute {
    @Override
    public void execute(GroupChatInfoDo groupChatInfoDo) {
        System.out.println("转交动作");
    }
}
//关闭
public class Cloes implements Execute {
    @Override
    public void execute(GroupChatInfoDo groupChatInfoDo) {
        System.out.println("关闭动作");
    }
}
//挂起
 public class HangUp implements Execute {
     @Override
     public void execute(GroupChatInfoDo groupChatInfoDo) {
         System.out.println("挂起动作");
     }
 }

第二步:

将动作封装成枚举(也可以使用策略模式来避免委派者模式违背开闭原则)

代码语言:javascript复制
public enum OperationEnum {
    CLOSE(new Cloes()),//关闭
    DISTRIBUTE(new Distribute()),//分配
    TRANSFER(new Transfer()),//转交
    HANGUP(new HangUp());//挂起
    private Execute execute;
    OperationEnum(Execute execute) {
        this.execute = execute;
    }
    public Execute getExecute() {
        return execute;
    }
}

第三步:

设置委派者(中介)

代码语言:javascript复制
public class Middleman {
    public static void center(OperationEnum operationEnum, GroupChatInfoDo groupChatInfoDo) {
        operationEnum.getExecute().execute(groupChatInfoDo);
    }
}

调用

代码语言:javascript复制
public class  Test{
    @Autowired
    private Middleman middleman;

    @RequestMapping("close")
    public void close(){
    middleman.center(OperationEnum.CLOSE);
    }
    
    @RequestMapping("distribute")
    public void distribute(){
    middleman.center(OperationEnum.DISTRIBUTE);
    }
}

这样设计首先简化了方法的调用,其次就是对内隐藏功能的实现。

0 人点赞