设计之美——代理模式

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

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

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

二、模式对比

1、非代理模式

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

本尊代码

public class ShopKeeper {

    //客户信息
    private Consumer consumer;

    public ShopKeeper(Consumer consumer){
        this.consumer = consumer;
    }

    //外卖订单信息
    public void send(){
        System.out.println(consumer.getConName() + "的订单,店长自己送,送到胶东路520弄,11:30之前送达...");
    }

}

客户代码

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等等,他们都是基于消息的发布的订阅机制,生产者和消费者之间没有必要有状态交互,你消费者挂了我生产者还是继续生产消息,互不影响,其实很多技术都是想通的,这里和代理模式就和类似。下面来看看代理模式是怎么处理的。

2、代理模式

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

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)接口

/**
 * 代理对象也需要实现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弄...

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

3、代理模式基本结构

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

}

测试结果

真实的请求

4、UML图

三、总结

代理模式一般用在一下几种场合。1、远程代理,也就是为了一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实。2、虚拟代理,是根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象。3、安全代理,用来控制真实对象访问是的权限。4、智能指引,是指当前调用真实的对象时,代理处理另外一些事情。所以代理模式还算比较常用的。

时间: 2024-10-24 13:38:56

设计之美——代理模式的相关文章

系统架构设计——设计模式之代理模式(二)CGLIB动态代理实现

像上一篇所说的代理模式其实是静态代理,在实际开发中其实应用不大,因为他需要事先知道被代理对象是谁,而且被代理对象和代理对象实现了公共的接口.实际情况往往并不能满足这些条件,我们往往在写代理模式的时候并不知道到时候被代理的对象是谁.解决办法就是--动态代理.以下我们将使用CGLIB实现动态代理. 一.动态代理概述 程序在运行期而不是编译器,生成被代理对象的代理对象,并且被代理对象并不需要和代理对象实现共同的接口.基于此,我们可以利用代理对象,提供一种以控制对被代理对象的访问. 1.1 动态代理的原

设计之美——模板方法模式

一.什么是模板方法模式 概念:定义一个操作中的算法的骨架,而将一字儿步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 通俗的讲,模板方法模式是通过把不变行为搬到超类,去除子类里面的重复代码提现它的优势,它提供了一个很好的代码复用平台.当不可变和可变的方法在子类中混合在一起的时候,不变的方法就会在子类中多次出现,这样如果摸个方法需要修改则需要修改很多个,虽然这个这个问题在设计之初就应该想好.这个时候模板方法模式就起到了作用了,通过模板方法模式把这些重复出现

代理模式(静态、动态)

代理模式的使用价值还是挺高的,各种框架中都用到了.把基础认真看看,学框架的时候也容易了. 关于静态代理: 代理模式的应用场景: 如果已有的方法在使用的时候需要对原有的方法进行改进,此时有两种办法: 1.修改原有的方法来适应.这样违反了“对扩展开放,对修改关闭”的原则. 2.就是采用一个代理类调用原有的方法,且对产生的结果进行控制.这种方法就是代理模式. 使用代理模式,可以将功能划分的更加清晰,有助于后期维护! 代理模式的要点: 1.“增加一层间接层”是软件系统中对许多负责问题的一种常见解决方法.

四、代理模式

1 代理模式? 为其他对象提供一种代理,用以完成对这个对象的控制访问. 记忆方法: /**  * 记忆方法:抽象出一个接口,代理类和真实的操作对象都实现接口  *               代理类中通过构造方法注入真实要操作的对象  *            代理中在调用真实对象的方法之前,完成验证.  */ 2 代理模式的应用场景? 应用一:远程访问!本地通过代理完成对远端的访问.那么为什么本地不直接去访问远端,非要经过一个代理呢?一种情况是你需要调用的对象在另外一台机器上,你需要跨越网络才

webgame设计之功能模块的代理模式

原文地址:http://chengduyi.com/blog/?post=27 在游戏设计中,通常会将一些实现了具体功能的模块进行封装,达到重用的目的.这些功能模块包括:1.网络通信模块(实现连接,断开,消息发送.接收,错误等处理):2.资源加载管理模块(实现资源加载,缓存,进度通知,分类型加载.管理等). 设计实现这些功能模块的方法很多,设计过程中最好做到使这些模块在外部启动简单.使用方便.重用容易. 我在设计中使用了代理模式的思想,就是将封装的功能留出一个代理类供外部继承实现.使用时候的具体

拦截器的设计思想——代理模式

代理模式:静态代理和动态代理 1.代理类和被代理类必须实现同一个借口 2.代理类和别代理类有一种关联关系 静态代理: 例如实现一个日志: //定义一个接口 public interface UserDao{ public void delete(); } //定义一个实现类 public class UserDaoImpl implements UserDao{ public void delete(){ System.out.pritln("成功删除"); } } //定义一个代理类

java设计优化--代理模式

代理模式使用代理对象完成用户的请求,屏蔽用户对真实对象的访问. 代理模式的用途很多,比如因为安全原因,需要屏蔽客户端直接访问真实对象:或者在远程调用中,需要使用代理对象处理远程方法中的技术细节:或者为了提升系统,对真是对象进行封装,从而达到延迟加载的目的. 在系统启动时,将消耗资源最多的方法使用代理模式分离,就可以加快系统的启动速度,减少用户的等待时间.在用户真正在做查询是,再由代理类加载真实的类,完成用户请求.这就是使用代理模式达到延迟加载的目的. 1.静态代理实现: 主题接口: 1 publ

C#面向对象设计之——代理模式(十三)

一.前言 代理模式是为其他对象提供一种代理以控制对这个对象的访问. 二.结构图 三.实例代码 namespace 代理模式 { class Program { static void Main(string[] args) { Proxy proxy = new Proxy(); proxy.Request(); Console.Read(); } } abstract class Subject { public abstract void Request(); } class RealSub

设计思想与模式之四静态代理模式

一 概述 1.什么是代理模式? 为了隐藏与保护目标对象,为其他对象提供一个代理以控制对该目标对象的访问. 2.什么是静态代理模式? 代理模式有两种: 静态代理:代理对象固定. 动态代理:代理对象不固定. 二 静态代理模式 1.基本结构: 父类:可以是一个接口.抽象类.一般类,一般是接口,保证可以按照操作目标对象的方式操作代理对象. 目标类:实现了父类. 代理类:不仅拥有与目标相同的父类,而且包含目标类对象. 2.代理类包含目标对象的实现 代理模式的作用是隐藏与保护目标对象,因此目标对象不能由用户