zoukankan      html  css  js  c++  java
  • 《图解设计模式》读书笔记9-2 Proxy模式

    Proxy模式

    Proxy是代理人的意思,指代替别人进行工作的人。

    代理人可以代替本人完成一部分工作,如果代理人自己完不成,再寻找本人完成。

    比如你委托租房中介帮你找房子,找房子的事情由他完成,需要签合同则由他来通知你亲自完成。

    示例程序

    程序描述

    下面一段程序实现了:遇到简单任务,由代理类PrinterProxy完成;遇到代理类完不成的任务,PrinterProxy交给Printer完成的功能。

    类图

    程序

    Printable接口

    定义了一个打印机所具备的功能(方法)

    public interface Printable {
        public abstract void setPrinterName(String name);   // 设置名字
        public abstract String getPrinterName();            // 获取名字
        public abstract void print(String string);          // 显示文字(打印输出)
    }
    
    

    Printer类

    实现了Printable接口的3个功能,增加了一个heavyJob方法,在构造类时调用,表示构造Printer类是一个耗时的过程

    public class Printer implements Printable {
        private String name;
        public Printer() {
            heavyJob("正在生成Printer的实例");
        }
        public Printer(String name) {                   // 构造函数
            this.name = name;
            heavyJob("正在生成Printer的实例(" + name + ")");
        }
        public void setPrinterName(String name) {       // 设置名字
            this.name = name;
        }
        public String getPrinterName() {                // 获取名字
            return name;
        }
        public void print(String string) {              // 显示带打印机名字的文字
            System.out.println("=== " + name + " ===");
            System.out.println(string);
        }
        private void heavyJob(String msg) {             // 重活
            System.out.print(msg);
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                }
                System.out.print(".");
            }
            System.out.println("结束。");
        }
    }
    

    PrinterProxy类

    也实现了Printable接口的功能,同时内部有一个Printer的实例。干“轻活”,比如设置和输出name时,只需要PrinterProxy类出马即可快速完成;直到干“重活”,即调用print方法时,才生成Printer的实例,让这个实例来完成工作。

    public class PrinterProxy implements Printable {
        private String name;            // 名字
        private Printer real;           // “本人”
        public PrinterProxy() {
        }
        public PrinterProxy(String name) {      // 构造函数
            this.name = name;
        }
        public synchronized void setPrinterName(String name) {  // 设置名字
            if (real != null) {
                real.setPrinterName(name);  // 同时设置“本人”的名字
            }
            this.name = name;
        }
        public String getPrinterName() {    // 获取名字
            return name;
        }
        public void print(String string) {  // 显示
            realize();
            real.print(string);
        }
        private synchronized void realize() {   // 生成“本人”
            if (real == null) {
                real = new Printer(name);
            }
        }
    }
    

    Main和结果输出

    public class Main {
        public static void main(String[] args) {
            Printable p = new PrinterProxy("Alice");
            System.out.println("现在的名字是" + p.getPrinterName() + "。");
            p.setPrinterName("Bob");
            System.out.println("现在的名字是" + p.getPrinterName() + "。");
            p.print("Hello, world.");
        }
    }
    
    现在的名字是Alice。
    现在的名字是Bob。
    正在生成Printer的实例(Bob).....结束。
    === Bob ===
    Hello, world.
    

    角色和类图

    角色

    • Subject(主体)

    Subject接口定义了使Proxy和RealSubject之间具有的统一接口。Subject角色的存在,使得Client不必在意它所使用的是Proxy角色还是RealSubject角色。本例中,由Printable接口扮演此角色。

    • Proxy(代理人)

    Proxy角色实现了Subject接口的API,会尽量处理来自Client的请求,只有当它不能处理时才将工作交给RealSubject角色。Proxy角色里面包含了一个RealSubject引用,只有必要时才会生成RealSubject角色。本例中由PrintProxy类扮演此角色。

    • RealSubject(实际的主体)

    RealSubject在Proxy无法胜任时出场,它与Proxy角色一样实现了Subject接口的API。本例中由Printer类扮演此角色。

    • Client(请求者)

    使用Proxy模式的角色,本例中由Main类扮演。

    模式类图

    思路拓展

    提升速度

    在本例中,把基础工作交给代理人来完成,将耗时的处理(生成实例)推迟至调用print方法时才进行。

    举一个实际的例子:打开一个包含大量图片的Word文档,文档不会一次加载所有图片,只有当用户浏览到图片时才加载,这样做能显著提升文档打开速度。

    代理与委托

    在程序中,代理人遇到自己无法处理的问题,会委托本人去处理。

    这里的委托是设计模式中的委托,指一个类调用另一个类的实例去完成一项工作。不要与现实生活中的委托搞混,它们的意思刚好相反。

    Http代理

    Http代理服务器是介于服务器和客户端之间的,为web页面提供高速缓存功能(实际上不止这一种功能)的软件。

    也可以认为其使用了代理模式。

    与其他模式的关联

    Decorator模式

    Decorator模式主要用来增加新功能

    Proxy模式更加侧重于通过代理人来减轻本人负担

  • 相关阅读:
    白话插件框架原理
    C# 可扩展编程MEF学习
    C#依赖注入实例
    迷你版AOP框架
    AOP 面向切面编程
    C++ 面向对象
    c++ 的异常处理
    C++ 模板 template
    c 二维数组动态分配和释放
    C++ 指针二维数组, C++二维指针数组笔记
  • 原文地址:https://www.cnblogs.com/qianbixin/p/11266700.html
Copyright © 2011-2022 走看看