设计模式:(代理模式)

1.定义

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。
在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。
简单来说:代理模式为其他对象提供一种代理以控制对这个对象的访问。

2.概述

当用户希望和某个对象打交道,但程序可能不希望用户直接访问该对象,而是提供一个特殊的对象,这个特殊的对象被称作当前用户要访问对象的代理,程序让用用户和对象的代理打交道,即让用户通过访问代理来访问想要访问的对象。在代理模式中,代理的特点是:它与所代理的对象实现了相同的接口,也就是说代理和它所代理的对象向用户公开了相同的方法,当用户请求代理调用这样的方法时,代理可能需要验证某些信息或检查它所代理的对象是否可用,当代理确认它所代理的对象能够电泳相同的方法时,就把实际的方法调用委派给它所代理的对象,即让所代理的对象调用同样的方法。
例如: 秘书是老板的代理,老板个秘书都有接听电话的方法:herePhone();
公司要求用户必须首先和秘书通电话才能和老板通电话,也就是说,用户必须首先请求秘书调用herePhone方法,当秘书确认老板可以接听电话时,就将用户的实际请求委派给老板,即让老板调用herePhone方法,如下所示:
设计模式:(代理模式)_第1张图片

3.应用场景

1、远程代理。
2、虚拟代理。
3、Copy-on-Write 代理。
4、保护(Protect or Access)代理。
5、Cache代理。
6、防火墙(Firewall)代理。
7、同步化(Synchronization)代理。
8、智能引用(Smart Reference)代理。

4.模式的结构和使用

代理模式主要包括三种角色
1.抽象主题(Subject):抽象主题是一个接口,该接口是对象和它代理所共有的接口,即是RealSubject角色和Proxy角色实例所共同实现的接口;
2.实际主题(ReaLSubject):实际主题是实现抽象主题接口的类。实际主题的实例是代理角色Proxy实例所要代理的对象;
3.代理(Proxy):代理是实现抽象主题接口的类。代理包含主题接口声明的变量,该变量用来存放RealSubject角色的实例引用,这样一来,代理的实例就可以控制对它所包含的RealSubject角色的实例访问,即可以控制对它所代理对象的访问。

1.代理模式的类图

前面所提到的Phone接口就是代理模式的抽象主题(Subject),Boss类就是实际主题(RealSubject)角色,Secretary类就睡代理角色(Proxy)。
设计模式:(代理模式)_第2张图片

2.结构的描述

以下通过一个简单的问题来描述怎么样使用代理模式,这个简单问题就是:
用户输入三个代表三角形三边长的数值,代理对象验证用户输入的三个数值是否能够构成三角形,如果能构成三角形,就创建一个三角形对象,并让该三角形对象计算自身的面积。
1.抽象主题(Subject)
定义了一个类名为Geometry的接口,里面定义了一个抽象方法getArea

package com.xing.proxy;
//几何图形接口
public interface Geometry {
   public double getArea();
}

2.实际主题(RealSubject)
在实际主题中,利用海伦公式给出了计算三角形面积的公式 ,实现了抽象方法getArea,代码如下所示:

package com.xing.proxy;

public class Triangle implements Geometry{
    double sideA,sideB,sideC,area;

    public Triangle(double sideA, double sideB, double sideC) {
        this.sideA = sideA;
        this.sideB = sideB;
        this.sideC = sideC;
    }
    //利用海伦公式计算三角形的面积
    //利用
    @Override
    public double getArea() {
        double p=(sideA+sideB+sideC)/2;
        return Math.sqrt(p*(p-sideA)*(p-sideB)*(p-sideC));
    }
}

3.代理
在代理类getArea方法中,如果用户输入的三条边可以构成三角形,则计算三角形面积,否则就不用创建三角形对象,直接返回-1;

package com.xing.proxy;

public class TriangleProxy implements Geometry{
    double sideA,sideB,sideC;
    Triangle triangle;

    public void setABC(double sideA, double sideB, double sideC) {
        this.sideA = sideA;
        this.sideB = sideB;
        this.sideC = sideC;
    }

    @Override
    public double getArea() {
        if(sideA+sideB>sideC && sideB+sideC>sideA && sideC+sideA>sideB){//满足条件则可以构成三角形
            triangle=new Triangle(sideA,sideB,sideC);
            double area = triangle.getArea();//让代理对象调用getArea方法
            return area;
        }else{
            return -1;
        }
    }
}

4.主程序测试

package com.xing.proxy;

import java.util.Scanner;

public class Application {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入三角形的三条边的长度");
        double a=sc.nextDouble();
        double b=sc.nextDouble();
        double c=sc.nextDouble();
        TriangleProxy proxy=new TriangleProxy();
        proxy.setABC(a,b,c);
        double area = proxy.getArea();
        System.out.println("面积是:"+area);
    }
}

5.测试结果展示:
设计模式:(代理模式)_第3张图片

5.代理模式的优点

1.代理模式可以屏蔽用户真正请求的对象,使用户程序和真正的对象之间解耦;
2.使用代理来担当那些创建耗时的对象的替身。

你可能感兴趣的:(java,设计模式,java,设计模式)