GOF设计模式——Proxy模式

1、什么是Proxy模式编程

        Proxy,代理的意思,它指的是代替别人进行工做的人。当不必定须要本人亲自进行工做时,就能够寻找代理人去完成工做。在面向对象编程时,“本人”和“代理人”都是对象,要记住的同样东西,就是代理人能够替代本人去作某些事情,意味着代理人和本人就具备必定程度相同的属性和方法。ide

2、Proxy模式的原理this

Subject:定义了使Proxy和RealSubject之间一致性的接口,上面也说起到,代理人和本人具备必定程度相同的属性和方法;spa

Proxy、RealSubject:这二者都实现了Subject接口,而且都有必定程度相同的属性;代理

Client:负责使用Proxy模式。code

3、Proxy模式示例对象

        这段示例实现了一个“带名字的打印机”。blog

一、Printable接口接口

package com.cjs.proxy; public interface Printable { public abstract void setPrinterName(String name);//设置名字
 
    public abstract String getPrinterName();//获取名字
 
    public abstract void print(String string);//显示名字,打印
}

二、Printer类get

package com.cjs.proxy; public class Printer implements Printable { private String name; private void heavyJob(String msg) { System.out.println(msg); for (int i = 0; i < 5; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.print("."); } } public Printer() { heavyJob("正在打印Printer实例"); } public Printer(String name) { this.name = name; heavyJob("正在打印Printer实例("+name+")"); } @Override public void setPrinterName(String name) { this.name = name; } @Override public String getPrinterName() { return name; } @Override public void print(String string) { System.out.println("=== " + name + " ==="); System.out.println(string); } }

        Printer类定义了name属性,用于设置和获取”打印机名“,还定义了一个heavyJob,作一些”重活“,这里是sleep5秒;

三、PrinterProxy类

package com.cjs.proxy; public class PrinterProxy implements Printable { private String name; private Printable real; private String className; public PrinterProxy() { } public PrinterProxy(String name, String className) { this.name = name; this.className = className; } @Override public void setPrinterName(String name) { if (real != null) { real.setPrinterName(name); } this.name = name; } @Override public String getPrinterName() { return name; } @Override 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 (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { System.out.println("没有找到"+className+"类"); } } } }

        PrinterProxy类,用于代理Printer完成名字的设置和获取,即一些简单的任务,因此PrinterProxy类也具备name属性,另外,还定义了Printable类型属性,用于操做实现了Printable接口的类;当须要完成”重活“时,就须要交给”本人“Printer类,即print方法。注意,执行print方法时,会调用realize方法,realize方法里面首先判断Printable类型的属性对象是否为null,不为null时,就建立一个这样的对象,这是根据类名来获取对象,可以有效的将PrinterProxy和Printer解耦,只要实现了Printable接口的类,就能够被PrinterProxy使用

四、Main类

package com.cjs.proxy; public class Main { public static void main(String[] args) { String className = "com.cjs.proxy.Printer";//这里是类的全名
        Printable p = new PrinterProxy("Alice", className); System.out.println("如今的名字是" + p.getPrinterName() + "."); p.setPrinterName("Bob"); System.out.println("如今的名字是" + p.getPrinterName() + "."); p.print("hello world"); } }

输出结果:

        在Main类中,一些简单的name设置和name获取,能够由PrinterProxy代理完成,到了print,则由真正的Printer类完成。

相关文章
相关标签/搜索