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類完成。

相關文章
相關標籤/搜索