代理模式

1、代理模式的概念

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。属于结构型模式。在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。

2、代理模式的特点

  • 创建具有现有对象的对象,向外界提供功能接口。

3、关于代理模式

  • 目的:为其他对象提供一种代理以控制对这个对象的访问。
  • 解决问题:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。
  • 使用时机:想在访问一个类时做一些控制。
  • 保证模式:增加中间层。
  • 关键:实现与被代理类组合。

4、优缺点

优点:

  • 职责清晰。
  • 高扩展性。
  • 智能化。

缺点:

  • 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
  • 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

5、使用场景

  • 远程代理。
  • 虚拟代理。
  • Copy-on-Write 代理。
  • 保护(Protect or Access)代理。
  • Cache代理。
  • 防火墙(Firewall)代理。
  • 同步化(Synchronization)代理。
  • 智能引用(Smart Reference)代理。

和适配器模式的区别

  • 适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。

6、代理模式的实现

将创建一个Image接口和实现了Image接口的实体类。ProxyImage是一个代理类,减少 RealImage对象加载的内存占用。ProxyPatternDemo类使用ProxyImage来获取要加载的 Image对象,并按照需求进行显示。如下图:
在这里插入图片描述
(1)创建接口和实现类

Image接口如下:

public interface Image {
    
    void display();

}

实现类RealImage如下:

public class RealImage implements Image{
    
    private String fileName;
    
    //构造方法
    public RealImage(String fileName) {
        this.fileName = fileName;
        this.loadFromDisk(fileName);
    }

    @Override
    public void display() {
        System.out.println("打开" + fileName + "图片!");     
    }
    
    //定义一个方法,模拟从硬盘上加载图片
    private void loadFromDisk(String fileName) {
        System.out.println("正在加载" + fileName + "图片!");
    }

}

(2)创建代理

创建Image接口的代理ProxyImage,对外提供Image接口的功能,如下:

public class ProxyImage implements Image {

    // 代理接口的实现类对象
    private RealImage realImage;

    private String fileName;

    // 构造方法
    public ProxyImage(String fileName) {
        this.fileName = fileName;
    }

    @Override
    public void display() {
        if (realImage == null) {
            realImage = new RealImage(fileName);
        }
        realImage.display();
    }

}

(3)测试

public class TestProxy {
    
    public static void main(String[] args) {
        
        Image image2 = new RealImage("狗狗.jpg");
        image2.display();
        System.out.println("------------------------");
        Image image = new ProxyImage("狗狗.jpg");
        image.display();

    }

}

执行,控制台输出:
在这里插入图片描述
可以看到,使用代理对象和使用接口的实现类的效果是一样的,代理只是在原类不方便对外开放的情况下,对外提供了访问,代理类是有原类的功能的,它代理原类向外开放,外部用户不必关心访问的是代理类还是原类,只要知道能实现一样的功能就行了。

7、总结

当你担心对外暴露结构会有很大的影响时,可以创建一个代理类来对外开放,代理类代表原类的功能,只向用户提供代理接口进行访问系统,内部构造不对用户开放,而用户并不知道他访问的是代理还是原生的,因为这不影响他的使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值