• 结构型模式


    代理模式(Proxy Pattern)

    简介

    一个类代表另一个类的功能。创建具有现有对象的对象,以便向外界提供功能的接口。

    意图

    为其他对象提供一种代理以控制这个对象的访问。

    特点

    主要解决:在直接访问对象时带来的问题,比如说,访问的对象在远程的机器上,在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大),或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。

    何时使用:想在访问一个类时做一些控制。
    如何解决:增加中间层。
    关键代码:实现与被代理类组合。
    应用实例:

    1. Windows快捷方式;
    2. 火车票代售点;
    3. 一张支票或银行存单,是资金的代理,支票是市场交易中用来替代现金,并对提供签发人账号上资金的控制;
    4. spring aop;
    • 优点
    1. 职责清晰;
    2. 高扩展性;
    3. 智能化;
    • 缺点
    1. 由于在客户端和真实主题之间增加了代理对象,请求处理速度可能变慢;
    2. 实现代理模式需要额外的工作,有些代理模式实现非常复杂;

    外观模式 vs 代理模式

    外观模式和代理模式都像用户提供访问内部对象的接口,它们有什么区别呢?

    1. 外观模式提供统一、唯一的接口给用户,主要是为了隐藏内部复杂性,简化交互,而代理并没有修改原有被代理对象的接口,主要是为了提供控制被代理对象的访问,代理接口与原接口一致。
    2. 外观模式提供的可能是一个系统(多个类)的接口的封装,而代理提供的一般是一个类、对象的访问控制。

    应用场景

    1. 远程代理;
    2. 虚拟代理;
    3. Copy-on-Write代理;
    4. 保护代理(Protect or Access);
    5. Cache代理;
    6. 防火墙代理(Firewall);

    代理模式 vs 适配器模式

    适配器模式主要改变所考虑对象接口(因为适配器模式是解决由于接口不兼容而不能使用的问题),而代理模式不能改变所代理类的接口。

    代理模式 vs 装饰器模式

    装饰器模式是为了增强功能(扩展原有类的功能),而代理模式是为了加以控制。

    UML类图

    实现代码

    1. 创建接口Image
    // Image.java
    public interface Image {
          public void display();
    }
    
    1. 创建实现接口的实体类
    // RealImage.java
    public class RealImage implements Image {
          private String fileName;
          
          public RealImage(String fileName) {
                this.fileName = fileName;
                loadFromDisk();
          }
          
          @Override
          public void display() {
                System.out.println("Image: RealImage display");
          }
          
          public void loadFromDisk() {
                System.out.println("RealImage: load image from path = " +  fileName);
          }
    }
    
    // ProxyImage.java
    public class ProxyImage implements Image{
          private RealImage realImage;
          private String fileName;
          
          public ProxyImage(String fileName) {
                this.fileName = fileName;
          }
          
          public void display() {
                if(null == realImage) {
                      realImage = new RealImage(fileName);
                }
                
                realImage.display();
          }
    }
    

    3.使用ProxyImage来获取RealImage类的对象

    // ProxyPatternDemo.java
    public class ProxyPatternDemo {
          public static void main(String[] args) {
                Image image = new ProxyImage("test.jpg");
                
                image.display(); // 从磁盘加载
                System.out.println("");
                image.display(); // 无需从磁盘加载
          }
    }
    

    运行结果

    RealImage: load image from path = test.jpg
    Image: RealImage display
    
    Image: RealImage display
    
  • 相关阅读:
    超链接
    Image中的alt
    预格式
    json字符串转json对象,json对象转换成java对象
    google-gson 解析json
    java HTTP请求工具
    JS文件中获取contextPath的方法
    eclipse中安装freemarker插件及ftl使用freemarker编辑器
    MyBatis 传入参数之parameterType
    typeAliases别名
  • 原文地址:https://www.cnblogs.com/fortunely/p/14267438.html
Copyright © 2020-2023  润新知