设计模式--代理模式(Proxy Pattern) 之 “高老庄悟空降八戒”

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式--代理模式(Proxy Pattern) 之 “高老庄悟空降八戒”相关的知识,希望对你有一定的参考价值。

参考技术A

说明:本文章引自<<Java与模式>>

高老庄的故事
  却说那春融时节,悟空牵着白马,与唐僧赶路西行。忽一日天色将晚,远远地望见一村人,这就是高老庄,猪八戒的老丈人高老太公家。为了将高家三小姐解救出猪八戒的魔掌,悟空决定假扮高小姐,挥一挥这妖怪:
  “行者却弄神通,摇身一变,变得就如那女子一般,婀娜多姿,沉鱼落雁,独自个坐在房里等那妖精。不多时,一阵风来,真个是走石飞砂……那阵狂风过处,只见半空里来了一个妖精,果然生得丑陋:黑脸短毛,长喙大耳,穿一领青不青、蓝不蓝的梭布直裰,系一条花布手巾……走进房,一把搂住,就要亲嘴……”

高小姐的神貌与本人
  悟空的下手之处是将高小姐的神貌和她本人分离开来。这与“开-闭”原则有异曲同工之妙。这样一来,高小姐本人就成了“高小姐神貌”的具体实现。而高小姐神貌就成了抽象角色,如下图所示。

悟空扮演并代替高小姐
  悟空巧妙地实现了“高小姐神貌”,也就是说同样变成了“高小姐神貌的”的子类。悟空可以扮演高小姐,并代替高小姐去会见猪八戒。其静态结构图如下图所示:

八戒分辨不出真假老婆
  从西游记的描述可以看出,八戒根本分不清楚悟空扮演的“高小姐替身”和“高小姐本人”。客户端分辨不出代理对象和真实对象。这是代理模式的一个重要用意。
  悟空代替高小姐会见八戒的对象图如下:

代理模式(Proxy Pattern)

代理模式

一、什么是代理模式

??代理模式(Proxy Pattern),指调用者通过调用代理对象来访问真实对象,在真实对象访问之前或者之后加入对应的逻辑,或者根据其他规则控制是否使用真实对象。代理对象需要和真实对象建立代理关系。

二、代理模式的步骤

  1. 代理对象和真实对象建立代理关系
  2. 实现代理对象的代理逻辑方法

三、代理模式的优缺点

1、优点

  1. 职责清晰。
  2. 高扩展性。
  3. 智能化。

2、缺点

  1. 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
  2. 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

四、代码实现

技术图片

1、代理模式中的角色

  1. 抽象对象角色:声明了目标类及代理类对象的共同接口,这样在任何可以使用目标对象的地方都可以使用代理对象。
  2. 目标对象角色:定义了代理对象所代表的目标对象。
  3. 代理对象角色:代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象;代理对象和目标对象具有统一的接口,以便可以再任何时候替代目标对象。代理对象通常在客户端调用传递给目标对象之前或者之后,执行某些操作,而非单纯的将调用传递给目标对象。

2、具体代码实现

/**
 * 抽象对象
 *
 * @author zt1994 2019/3/2 16:25
 */
public interface SayHello {

    void sayHelloWorld();
}
/**
 * 真实对象
 *
 * @author zt1994 2019/3/2 16:27
 */
public class SayHelloImpl implements SayHello {

    @Override
    public void sayHelloWorld() {
        System.out.println("Hello World!");
    }
}
/**
 * 代理对象
 *
 * @author zt1994 2019/3/2 16:28
 */
public class SayHelloProxy implements SayHello {

    private SayHello sayHello;

    public SayHelloProxy(SayHello sayHello) {
        this.sayHello = sayHello;
    }

    @Override
    public void sayHelloWorld() {
        System.out.println("调用sayHello之前的处理");
        sayHello.sayHelloWorld();
        System.out.println("调用sayHello之后的处理");
    }
}
/**
 * 测试静态代理
 *
 * @author zt1994 2019/3/2 16:30
 */
public class staticProxyTest {

    /**
     * 测试静态代理
     */
    @Test
    public void testStaticProxy() {
        SayHelloImpl sayHello = new SayHelloImpl();
        sayHello.sayHelloWorld();

        SayHelloProxy sayHelloProxy = new SayHelloProxy(sayHello);
        sayHelloProxy.sayHelloWorld();
    }
}

测试结果:
Hello World!
调用sayHello之前的处理
Hello World!
调用sayHello之后的处理

源码地址:https://github.com/zt19994/designPattern

以上是关于设计模式--代理模式(Proxy Pattern) 之 “高老庄悟空降八戒”的主要内容,如果未能解决你的问题,请参考以下文章

设计模式(十三)代理模式(Proxy Pattern)

代理模式(Proxy Pattern)

代理模式(Proxy Pattern)

设计模式之- 代理模式(Proxy Pattern)

设计模式之 - 代理模式(Proxy Pattern)

代理模式(Proxy Pattern)