zoukankan      html  css  js  c++  java
  • 设计模式学习笔记(十九:代理模式)

    1.1概述

        为其他对象提供一种代理以控制对这个对象的访问。这就是代理模式的定义。

        当用户希望和某个对象打交道,但程序可能不希望用户直接访问该对象,而是提供一个特殊的对象,这个特殊的对象被称作当前用户要访问对象的代理,程序让用户和对象的代理打交道,即让用户通过访问代理来访问想要访问的对象。在代理模式中,代理的特点是:它与所代理的对象实现了相同的接口,也就是说代理和它多代理的对象向用户公开了相同的方法,当用户请求代理调用该方法时,代理可能需要验证某些信息或检查它所代理的对象是否可用,当代理确认它所代理的对象能调用箱通风的方法时,就把实际的方法调用委派给它所代理的对象,即让所代理的对象调用同样的方法。

      例如,公司里的秘书是老板的代理,老板和秘书都有听电话的方法:herePhone()。公司要求用户必须首先和秘书通电话才能和老板通电话,也就是说,用户必须首先请求秘书调用herePhone(),当秘书确认老板可以接电话时,就将用户的实际请求委派给老板,即让老板调用herePhone()方法。具体类关系如下图一所示:

     

    图一:老板和秘书

    1.2模式的结构

    代理模式包括以下三种角色:

    (1)抽象主题(Subject):抽象主题是一个接口,该接口是对象和它的代理所共用的接口,即是RealSubject角色和Proxy角色实例所实现的接口。

    (2)实际主题(RealSubject):实际主题是实现抽象主题接口的类。实际主题的实例是代理角色(Proxy)实例所要代理的对象。

    (3)代理(Proxy):代理是实现抽象主题接口的类(代理和实际主题实现了相同的接口)。代理含有主题接口声明的变量,该变量用来存放RealSubject角色的实例引用,这样一来,代理的实例就可以控制对它所包含的RealSubject角色的实例访问,即可以控制对它所代理对象的访问。

    代理模式结构的类图如下图二所示:

     

    图二:代理模式的类图

     

     

    1.3代理模式的优点

    1)代理模式可以屏蔽用户真正请求的对象,使用户程序和真正的对象之间解耦。

    2)使用代理来担当那些创建耗时的对象的替身。

    1.4适合使用代理模式的情景

    1)程序可能不希望用户直接访问该对象,而是提供一个特殊的对象以控制对当前对象的访问。

    2)如果一个对象(例如很大的图像)需要很长时间才能加载完成。

    3)如果对象位于远程主机上,需要为用户提供访问该远程对象的能力。

    1.5代理模式的使用

    以下通过一个简单的问题来描述怎样使用代理模式,这个简单的问题是:用户输入三个代表三角形三边长度的数值,代理对象验证用户输入的三个数值是否能构成三角形,如果能构成三角形,就创建一个三角形对象,并让该三角形对象计算自身的面积。

     首先看一下本实例构建框架具体类和1.2模式的结构中类图的对应关系,如下图所示:

    (1)抽象主题(Subject

    本问题中,抽象主题角色是Geometry接口,Geometry接口的代码如下:

    package com.liuzhen.nineteen_proxy;
    
    public interface Geometry {
        public double getArea();
    }

    (2)实际主题(RealSubject

    对于本问题,实际主题(RealSubject)是Triangle类,代码如下:

    package com.liuzhen.nineteen_proxy;
    
    public class Triangle implements Geometry {
    
        double sideA, sideB, sideC, area;
        
        public Triangle(double a,double b,double c){
            sideA = a;
            sideB = b;
            sideC = c;
        }
        
        public double getArea() {
            double p = (sideA+sideB+sideC)/2.0;
            area = Math.sqrt(p*(p-sideA)*(p-sideB)*(p-sideC));
            return area;
        }
    
    }

    (3)代理(Proxy

    对于本问题,代理是TriangleProxy类,代码如下:

    package com.liuzhen.nineteen_proxy;
    
    public class TriangleProxy implements Geometry {
    
        double sideA, sideB, sideC;
        Triangle triangle;
        
        public void setABC(double a,double b,double c){
            sideA = a;
            sideB = b;
            sideC = c;
        }
        
        public double getArea() {
            if(sideA+sideB > sideC && sideA+sideC > sideB && sideB+sideC > sideA){
                triangle = new Triangle(sideA,sideB,sideC);
                double area = triangle.getArea();   //让所代理的对象调用getArea()方法
                return area;
            }
            else
                return -1;
        }
    
    }

    (4)具体使用

          通过NineteenApplication类来具体实现上述相关类和接口,来实现代理模式的运用,其代码如下:

    package com.liuzhen.nineteen_proxy;
    
    import java.util.Scanner;
    
    public class NineApplication {
        
        public static void main(String[] args){
            Scanner reader = new Scanner(System.in);
            System.out.println("请输入三个数,每输入一个数按回车确认:");
            double a, b , c;
            a = reader.nextDouble();
            b = reader.nextDouble();
            c = reader.nextDouble();
            TriangleProxy proxy = new TriangleProxy();
            proxy.setABC(a, b, c);
            double area = proxy.getArea();
            System.out.println("面积是:"+area);
        }
        
    }

    运行结果:

    请输入三个数,每输入一个数按回车确认:
    20
    20
    20
    面积是:173.20508075688772

    参考资料:

          1.Java设计模式/耿祥义,张跃平著.——北京:清华大学出版社,2009.5

     

     

  • 相关阅读:
    【软件工程】第0次个人作业
    【面向对象设计与构造】第四次博客作业
    【面向对象设计与构造】第三次博客作业
    【面向对象设计与构造】第二次博客作业
    【面向对象设计与构造】第一次博客作业
    软件工程提问回顾与个人总结
    软件工程结对项目博客作业
    软件工程第一次阅读作业
    软件工程第0次个人作业
    面向对象设计与构造第四次总结作业
  • 原文地址:https://www.cnblogs.com/liuzhen1995/p/6040884.html
Copyright © 2011-2022 走看看