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对象了。 

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

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

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

原文地址:https://www.cnblogs.com/sunshine798798/p/10039692.html