zoukankan      html  css  js  c++  java
  • GOF设计模式——Proxy模式

    一、什么是Proxy模式

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

    二、Proxy模式的原理

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

    Proxy、RealSubject:这两者都实现了Subject接口,并且都有一定程度相同的属性;

    Client:负责使用Proxy模式。

    三、Proxy模式示例

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

    1、Printable接口

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

    2、Printer类

    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秒;

    3、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使用

    4、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类完成。

  • 相关阅读:
    LASSO回归原理和Python代码 | 线性回归 | 交叉验证
    初探投行 | 金融
    癌症疫苗 | Cancer Vaccines
    文献复现 | Machine Learning on Human Muscle Transcriptomic Data for Biomarker Discovery and TissueSpecific Drug Target Identification
    癌症研究必备基础知识 | 生信
    初探RNA | RNA分类 | miRNA | lncRNA
    PubMed文献数据挖掘
    罕见病 | 国内 | 国外 | 市场状态
    医保目录谈判 | 国家带量采购 | DRG/DIP支付方式改革 | 腾笼换鸟
    TCGA数据挖掘基本教程
  • 原文地址:https://www.cnblogs.com/SysoCjs/p/10399056.html
Copyright © 2011-2022 走看看