JAVA设计模式设计模式Android知识

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

2017-07-22  本文已影响344人  六尺帐篷
  • 代理模式的引入

代理模式的引入

Proxy是代理人的意思,指的是代替别人进行工作的人。当不一定需要本人亲自去做的工作的时候,就可以寻找代理人去完成。
但在代理模式中,往往是相反的,通常是代理人碰到工作,就交给被代理的对象去完成,代理人只完成一些准备工作或者收尾工作。
如果读者了解过spring框架的话,就会知道aop也就是面向切面编程其实运用的就是动态代理模式,这可以让被代理的对象专注于完成自己的本职工作,而代理对象可以进行工作前的日志记录,时间计算,在工作之后进行日志记录,收尾工作等附加的功能,需要正式做工作的时候就交给被代理去做。就像插了两个刀到这个被代理的对象前后。所以形象的叫做面向切面编程。
关于动态代理模式和静态代理模式,感兴趣的读者可以参考笔者的另一篇博文:
Java动态代理与静态代理http://www.jianshu.com/p/b5e340ec9551

代理模式的实例程序

我们会实现一个打印机,向屏幕打印一串字符串,然后交给代理对象去完成这个功能。

首先看一下类图:

image.png

Printer类:

package Proxy;

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("结束。");
    }
}

Printable接口:

package Proxy;

public interface Printable {
    public abstract void setPrinterName(String name);
    
    public abstract String getPrinterName();
    
    public abstract void print(String string); 
}

PrinterProxy类,利用反射机制,动态生成被代理的对象,并且延迟初始化到需要调用它的时候再初始化

package Proxy;

public class PrinterProxy implements Printable {
    private String name;            // 名字
    private Printable real;         // “本人”                 
    private String className;       // “本人”的类名       
    public PrinterProxy(String name, String className) {      // 构造函数     
        this.name = name;
        this.className = className;                                                 
    }
    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) {
            try {                                                                       
                real = (Printable)Class.forName(className).newInstance();               
                real.setPrinterName(name);                                              
            } catch (ClassNotFoundException e) {                                        
                System.err.println("没有找到 " + className + " 类。");      
            } catch (Exception e) {                                                     
                e.printStackTrace();                                                    
            }                                                                           
        }
    }
}

Main类测试:

package Proxy;

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

运行结果:

image.png

代理模式分析

代理模式中的角色:

代理模式的类图:

image.png
上一篇 下一篇

猜你喜欢

热点阅读