设计模式之代理模式

1、什么是代理模式(Porxy)

  概念:代理模式就是为其余对象提供一种代理以控制对这个对象的访问。安全

  现实生活中也有不少行为吻合代理模式。好比店外卖,客户在APP上下单后,店长会接单。这个时候店长能够选择本身去送这份外卖,也能够委托送餐员代理店长去送这份外卖。固然店长是能够本身送,但店长送了外卖店就没人看着了,而让送餐员代理送外卖就不会这样了。这里很显然店长是对象本尊(Subject),送餐员是代理对象(Proxy ),代理对象中有店长给的订单信息,好比送到哪里,几点以前要送到,这就说明代理对象中须要包含本尊。下面根据实际代码来讲明代理模式和非代理的具体实现。ide

2、模式对比

一、非代理模式

非代理模式即店长本身送,无须委托送餐员代理送。即直接建立本尊对象并访问本尊方法,没有中间的代理对象。测试

本尊代码this

public class ShopKeeper {

    //客户信息
    private Consumer consumer;
    
    public ShopKeeper(Consumer consumer){
        this.consumer = consumer;
    }
    
    //外卖订单信息
    public void send(){
        System.out.println(consumer.getConName() + "的订单,店长本身送,送到胶东路520弄,11:30以前送达...");
    }
    
}

客户代码spa

public class Consumer {

    private String conName;
    
    public Consumer(String conName){
        this.conName = conName;
    }

    public String getConName() {
        return conName;
    }
}

客户端测试代码代理

public class Show {

    public static void main(String[] args) {
        Consumer consumer = new Consumer("Tom");
        ShopKeeper shopKeeper = new ShopKeeper(consumer);
        shopKeeper.send();
    }
    
}

这样店长和客户的代码就耦合在一块儿,不利于后期维护升级。再者店长和客户原本就不须要相互包含,他们之间是无状态的。像不少pub/sub的中间件,好比dubbo,activeMQ等等,他们都是基于消息的发布的订阅机制,生产者和消费者之间没有必要有状态交互,你消费者挂了我生产者仍是继续生产消息,互不影响,其实不少技术都是想通的,这里和代理模式就和相似。下面来看看代理模式是怎么处理的。code

二、代理模式

提供了一个共有的送外卖接口中间件

public interface Send {

    void sendName();
    void sendTime();
    void sendAddress();
    
}

店长本尊对象,实现了共有的送外卖接口。对象

/**
 * 店长对象(本尊)须要实现Send接口
 * @author user
 */
public class ShopKeeper implements Send{

    private Consumer consumer;
    
    public ShopKeeper(Consumer consumer){
        this.consumer = consumer;
    }
    
    @Override
    public void sendName() {
        System.out.print(consumer.getConName() + "的订单,");
    }
    
    @Override
    public void sendTime() {
        System.out.print("12:00以前送达,");
    }

    @Override
    public void sendAddress() {
        System.out.print("送到长岛路520弄,由代理对象配送...");
    }

新增了代理对象,代理对象须要包含本尊,而且也要实现送外卖(Send)接口blog

/**
 * 代理对象也须要实现Send接口
 * @author user
 *
 */
public class ProxySend implements Send{

    private ShopKeeper shopKeeper;
    
    public ProxySend(Consumer consumer){
        this.shopKeeper = new ShopKeeper(consumer);
    }
    
    @Override
    public void sendName() {
        shopKeeper.sendName();
    }

    @Override
    public void sendTime() {
        shopKeeper.sendTime();
    }

    @Override
    public void sendAddress() {
        shopKeeper.sendAddress();
    }

}

客户对象没有变化

public class Consumer{
    
    private String conName;

    public String getConName() {
        return conName;
    }

    public void setConName(String conName) {
        this.conName = conName;
    }
}

客户端测试代码

public class Show {

    public static void main(String[] args) {
        
        Consumer consumer = new Consumer();
        consumer.setConName("外卖张");
        ProxySend proxy = new ProxySend(consumer);
        proxy.sendName();
        proxy.sendTime();
        proxy.sendAddress();
        
    }
    
}

看输出

外卖张的订单,12:00以前送达,送到长岛路520弄...

这样代理对象就帮本尊完成了任务,能够看到客户端的代码变化很大,客户端根本不知道本尊的存在,由于在客户端代码中至始至终都没有看到本尊对象的建立,连实例都没有,这其实就是代理对象的做用之一,隐藏本尊。

三、代理模式基本结构

Subject类,定义了RealSubject和Proxy的共用接口,这样就在任何使用RealSubject的地方均可以使用Proxy,这里使用抽象类

public abstract class Subject {

    public abstract void request(); 
    
}

RealSubject类,定义了Proxy所表明的真是实体

public class RealSubject extends Subject {

    @Override
    public void request() {
        System.out.println("真实的请求");
    }

}

Proxy类,保存了一个引用使得代理对象能够访问实体对象,并提供一个与Subject的接口相同的接口,这样代理就能够用来代理实体。

public class Proxy extends Subject{

    RealSubject realSubject;
    
    @Override
    public void request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        realSubject.request();
    }

}

客户端代码

public class Show {

    public static void main(String[] args) {
        Proxy proxy = new Proxy();
        proxy.request();
    }
    
}

测试结果

真实的请求

四、UML图

3、总结

代理模式通常用在一下几种场合。一、远程代理,也就是为了一个对象在不一样的地址空间提供局部表明。这样能够隐藏一个对象存在于不一样地址空间的事实。二、虚拟代理,是根据须要建立开销很大的对象。经过它来存放实例化须要很长时间的真实对象。三、安全代理,用来控制真实对象访问是的权限。四、智能指引,是指当前调用真实的对象时,代理处理另一些事情。因此代理模式还算比较经常使用的。

相关文章
相关标签/搜索