设计模式-委派模式

委派模式(Delegate Pattern)又叫委托模式,是一种面向对象的设计模式,允许对象组合实现与 继承相同的代码重用。它的基本作用就是负责任务的调用和分配任务,是一种特殊的静态代理,可以理 解为全权代理,但是代理模式注重过程,而委派模式注重结果。委派模式属于行为型模式,不属于 GOF 23 种设计模式中。

通俗点讲就是有两个对象参与(两个对象协同)处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。

委派模式的UML类图

可以发现和静态代理类的类图一样,所以也叫做特殊的静态代理,唯一的区别就是关注点不一样,一个是过程一个是结果

代码如下:

public interface Task {
    void doSomething();
}
复制代码
public class ConcreteA implements Task{
    @Override
    public void doSomething() {
        System.out.println("ConcreteA doSomething");
    }
}
复制代码
public class ConcreteB implements Task{
    @Override
    public void doSomething() {
        System.out.println("ConcreteB doSomething");
    }
}
复制代码
public class Delegate implements Task{
    private Task task = new ConcreteA();

    @Override
    public void doSomething() {
        task.doSomething();
    }

    public void toA(){
        task = new ConcreteA();
    }

    public void toB(){
        task = new ConcreteB();
    }
}
复制代码
public class Test {
    public static void main(String[] args) {
        Delegate delegate = new Delegate();
        delegate.doSomething();
        delegate.toB();
        delegate.doSomething();
    }
}
复制代码

代码示例

举个典型的例子:路由,我们知道路由的作用就是在不同网段之间转发数据的,当路由器接受到一个消息的时候她会根据消息头部中的信息找出对应网段再根据自己的路由表找到对应的机器再转发给实际接收者,这里面路由就是一个委托者角色而注册到这个路由中的计算机则是实际执行任务的角色(实际接收消息的角色)
消息体:

@Data
public class Message {
    private String content;
    private String targetIp;
    private String sourceIp;

    public Message(String content, String targetIp, String sourceIp) {
        this.content = content;
        this.targetIp = targetIp;
        this.sourceIp = sourceIp;
    }
}
复制代码
  1. 首先抽象出任务的角色

     public interface IMessage {
         void receiveMessage(Message message);
     }
    复制代码
  2. 具体任务实现对象

     @Data
     public class ComputerA implements IMessage{
         private String ip = "192.168.88.7";
         @Override
         public void receiveMessage(Message message) {
             System.out.println("ComputerA处理消息:" + message.getContent());
         }
     }
    复制代码
    @Data
    public class ComputerB implements IMessage{
        private String ip = "192.168.88.8";
        @Override
        public void receiveMessage(Message message) {
            System.out.println("ComputerB处理消息:" + message.getContent());
        }
    复制代码
    @Data
    public class ComputerC implements IMessage{
        private String ip = "192.168.88.9";
        @Override
        public void receiveMessage(Message message) {
            System.out.println("Computerc处理消息:" + message.getContent());
        }
    }
    复制代码
  3. 委托者角色

     public class Route implements IMessage{
         private final Map<String, IMessage> routeTable= new HashMap<>();
         public Route(){
             ComputerA computerA = new ComputerA();
             ComputerB computerB = new ComputerB();
             ComputerC computerC = new ComputerC();
             routeTable.put(computerA.getIp(),computerA);
             routeTable.put(computerB.getIp(),computerB);
             routeTable.put(computerC.getIp(),computerC);
         }
    
         @Override
         public void receiveMessage(Message message) {
             if(routeTable.containsKey(message.getTargetIp())){
                 routeTable.get(message.getTargetIp()).receiveMessage(message);
             }
         }
     }
    复制代码

    这里用了策略模式配合使用

  4. 客户端调用

    public class Test {
       public static void main(String[] args) {
           Message message = new Message("hello","192.168.88.7","192.168.88.100");
           Route route = new Route();
           route.receiveMessage(message);
       }
    }
    复制代码
  5. 打印结果

  6. UML类图

源码中的应用

jvm在加载类的时候使用的就是双亲委派,就是在加载类之前会先找父类,如果存在父类则继续找父类的父类知道找到最顶级的父类然后加载返回即可,如果没有父类则加载类然后返回,具体源码我们可以看一下 ClassLoader这个类:

委派模式优缺点

优点:

  1. 通过任务委派能够将一个大型的任务细化。
  2. 将应用相关的内容与框架完全分离开
  3. 避免过多的子类以及子类与父类的耦合
  4. 通过委托传递消息机制实现分层解耦

缺点:
任务委派方式需要根据任务的复杂程度进行不同的改变,在任务比较复杂的情况下可能需要进行多 重委派,容易造成紊乱。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值