zoukankan      html  css  js  c++  java
  • Java设计模式之代理模式初识

    概论

     什么是代理模式呢?代理模式是这么定义的:为其他对象提供一种代理以控制对这个对象的访问。

    代理模式示例

    代理模式中有三种角色,分别是抽象主题角色,具体主题角色和代理主题角色。

    1.抽象主题角色指的是抽象的行为,往往使用接口或者抽象类来表达。或者使用接口和抽象类混合使用。

    2.具体主题角色指的是具体的行为,该行为是抽象行为的具体化,也是抽象行为的具体表达,即抽象行为的实现类或者子类。

    3.代理主题角色指的是代理具体行为的一种角色,它的存在就是代替具体对象,并且灵活控制具体对象的表达。

    我们以网上购物为例。首先我们需要有一个购物消费者接口,用来定义购物的行为:

    1.账号登录。

    2.生成订单。

    3.订单支付。

    1 public interface IConsumer {
    2 
    3     public void login(String name, String password);
    4 
    5     public void order(String goodsName);
    6 
    7     public void pay();
    8 
    9 }

    再来新增一个具体的消费者。具体的行为。

     1 public class RealConsumer implements IConsumer {
     2     @Override
     3     public void login(String name, String password) {
     4         System.out.println("["+name+"]登陆成功");
     5     }
     6 
     7     @Override
     8     public void order(String goodsName) {
     9 
    10         System.out.println("["+goodsName+"]生成订单成功");
    11 
    12     }
    13 
    14     @Override
    15     public void pay() {
    16 
    17         System.out.println("订单支付成功");
    18 
    19     }
    20 }

    我们再来定义一个场景类Client:

     1 public class Client {
     2 
     3     public static void main(String[] args) {
     4 
     5         IConsumer consumer = new RealConsumer();
     6 
     7         consumer.login("抒尽", "123456");
     8         consumer.order();
     9         consumer.pay();
    10 
    11     }
    12 }

    场景类中直接创建真实的消费者,这个消费者再进行购物的一系列的动作。那么问题来了,天天自己买东西太累了,找个人来代理购物这个行为。于是我们需要增加一个代理的角色,我们把它叫作代理类。

     1 public class ProxyConsumer implements IConsumer {
     2 
     3     private IConsumer consumer = null;
     4 
     5     public ProxyConsumer(IConsumer consumer) {
     6         this.consumer = consumer;
     7     }
     8 
     9     @Override
    10     public void login(String name, String password) {
    11         consumer.login(name, password);
    12     }
    13 
    14     @Override
    15     public void order() {
    16         consumer.order();
    17 
    18     }
    19 
    20     @Override
    21     public void pay() {
    22         consumer.pay();
    23     }
    24 }

    第1行:代理消费者依然是消费接口的实现类。

    第3行:代理消费者持有真实消费者的引用。

    第5行-7行,真实消费者是在场景类中以参数形式传递给代理消费者。

    第11行,16行,22行:使用真实消费者对象参与购物的所有动作。

    最后我们再来修改一下场景类。

    public class Client {
    
        public static void main(String[] args) {
    
            IConsumer realConsumer = new RealConsumer();
    
            IConsumer proxyCosumer = new ProxyConsumer(realConsumer);
    
            proxyCosumer.login("抒尽", "123456");
            proxyCosumer.order();
            proxyCosumer.pay();
    
        }
    }

    运行结果如下所示:

    [抒尽]登陆成功
    生成订单成功
    订单支付成功

    OK,执行的结果没有任何变化,本来是自己要去做的动作,结果可以找代理来做,这就是代理模式。代理模式最大的特点就是把控了真实对象的定位,例如我们需要打印生成订单的时间,统计生成订单到支付成功的时间。支付之后,增加业务接口回调。如果在真实接口中,除了扩展代码之后别无其他任何选择,这就违背的开闭的原则。不变的部分和变化的部分需要分离。

    代理模式的优点和使用场景

    1.职责清晰。真实的角色实现真实的业务逻辑。其他逻辑,比如打印时间,日志处理,事务处理就交给了代理角色。

    2.高扩展性。代理对象会跟着真实对象的变化而变化,真实对象业务发生了变化,代理对象不需要修改任何东西,跟着发生变化。

    3.智能化。尤其是接下来要介绍的spring中aop采用的动态代理。这个特性把智能化的特点表现的淋漓尽致。

    使用场景:在spring源代码aop部分非常巧妙使用了动态代理。

    代理模式的分类

    代理模式分为三类:普通代理,强制代理,动态代理。

    什么是普通代理呢?要求场景类只能访问代理角色,而不能直接访问真实角色,在上面的例子中,我们不能够在场景类中直接去产生一个realConsumer对象了。 

    什么是强制代理呢?强制代理和普通代理刚好相反。必须要通过真实角色找到代理角色。

    什么是动态代理呢?动态代理在实现阶段,即代码阶段不需要关心谁代理谁,而是在运行阶段才去确定代理类。

    既然有动态代理,那必然有静态代理,静态代理指的是手工去构建代理类,因此静态代理包括了普通代理和强制代理。

  • 相关阅读:
    关闭firefox的plugincheck
    C# 三个定时器区别
    数字图像处理学习 01 图像的几何变换
    C++ dll的创建和使用
    使用Log4Cplus+配置文件打印日志
    Bmp图像的数据格式及读取
    GCC的使用和Makefile的编写
    day03 QT学习 常用控件 QLabel QPushButton QLineEdit使用 QSS介绍以及QObject子对象的遍历
    day02 QT学习 字符集和中文乱码的问题
    day01 QT学习 信号槽和QWidget介绍
  • 原文地址:https://www.cnblogs.com/sunshine798798/p/10039692.html
Copyright © 2011-2022 走看看