当前位置: 首页 >  网技达人 >  软件设计模式系列之十四——代理模式

软件设计模式系列之十四——代理模式

导读:1 模式的定义.代理模式是一种结构型设计模式,它允许一个对象(代理)充当另一个对象的接口,以控制对该对象的访问。代理模式通常用于控制对真实对象的访问,以实现一些额外的功能,例如延迟加载、权限控制、日志记录等。这种模式属于结构型设计模式,因为它关注对象之间的组合,以形成更大的结构。

1 模式的定义

代理模式是一种结构型设计模式,它允许一个对象(代理)充当另一个对象的接口,以控制对该对象的访问。代理模式通常用于控制对真实对象的访问,以实现一些额外的功能,例如延迟加载、权限控制、日志记录等。这种模式属于结构型设计模式,因为它关注对象之间的组合,以形成更大的结构。

代理模式有多种类型,包括静态代理和动态代理。静态代理在编译时创建代理对象,而动态代理在运行时创建代理对象。代理模式的核心思想是通过引入一个代理对象来控制对真实对象的访问,从而实现额外的功能,而不必修改真实对象的代码。

2 举例说明

为了更好地理解代理模式,让我们看几个日常生活中的简单示例。
一个最典型的例子就是狐假虎威,狐狸就做了老虎的代理。

银行代理。在银行业务中,某些操作需要前往银行分行才能完成,但人们不一定都会前往分行。因此,银行通常设立代理机构,例如ATM(自动取款机)和在线银行,允许客户在不必亲自前往分行的情况下进行银行业务。

网络代理。防火墙和代理服务器是网络中常见的代理示例。防火墙代理可以过滤和控制网络流量,而代理服务器可以缓存和优化网络请求,提高网络性能。

租房中介。在房地产市场中,房屋租赁中介机构充当租客和房东之间的代理。中介机构帮助租客找到合适的房源,同时为房东管理租赁过程,收取一定的服务费。

电影票代理。在线电影票代理网站允许观众在不必亲自前往电影院的情况下购买电影票。这些代理网站提供了方便的在线订票和座位选择功能。

社交媒体代理。在社交媒体上,一些名人或公众人物可能雇佣社交媒体代理来管理他们的社交媒体账户。这些代理负责发布内容、与粉丝互动,以代表名人或公众人物维护其在线存在。

这些示例都展示了代理模式的核心思想:允许一个对象(代理)充当另一个对象(真实对象)的接口,以控制对真实对象的访问,同时可以添加额外的功能或服务。这种模式在日常生活中有着广泛的应用,以提供更便利的服务和更好的控制。

3 结构

代理模式的结构包括以下几个关键部分:

Subject(主题):定义了真实对象和代理对象的共同接口,以确保代理对象可以替代真实对象。在示例中,ImageLoader 就是主题。

RealSubject(真实主题):代表真实对象,它是实际执行工作的类。在示例中,ImageLoader 是真实主题。

Proxy(代理):充当了真实主题的代理,实现了与真实主题相同的接口。它可以在执行任务前后添加额外的功能。在示例中,ImageLoaderProxy 是代理。

4 实现步骤

实现代理模式时,通常遵循以下步骤:

定义主题接口(Subject):这个接口应该包含真实主题和代理类都必须实现的方法。

创建真实主题类(RealSubject):这个类负责执行实际的工作,实现主题接口的方法。

创建代理类(Proxy):代理类实现了主题接口,并包含一个对真实主题对象的引用。它可以在调用真实主题的方法前后添加额外的逻辑。

在客户端代码中使用代理:客户端代码不直接与真实主题交互,而是通过代理对象来访问真实主题。

5 代码实现

假设我们有一个图像加载器类 ImageLoader,它负责从磁盘或网络加载图像并显示在界面上。现在,我们想要在加载图像之前检查用户的权限以确保他们有权查看该图像。

在这个示例中,我们可以创建一个代理类 ImageLoaderProxy,它充当了 ImageLoader 的接口。在代理类中,我们可以添加权限检查的逻辑,然后再调用真实的 ImageLoader 对象来加载图像。

// 1. 定义主题接口
interface ImageLoader {
    void displayImage();
}

// 2. 创建真实主题类
class RealImageLoader implements ImageLoader {
    private String image;

    public RealImageLoader(String image) {
        this.image = image;
    }

    @Override
    public void displayImage() {
        System.out.println("Displaying image: " + image);
    }
}

// 3. 创建代理类
class ImageLoaderProxy implements ImageLoader {
    private RealImageLoader realImageLoader;
    private String image;
    private String user;

    public ImageLoaderProxy(String image, String user) {
        this.image = image;
        this.user = user;
    }

    @Override
    public void displayImage() {
        // 在调用真实主题前检查用户权限
        if (user.equals("admin")) {
            realImageLoader = new RealImageLoader(image);
            realImageLoader.displayImage();
        } else {
            System.out.println("Access denied. You do not have permission to view this image.");
        }
    }
}

// 4. 在客户端代码中使用代理
public class Client {
    public static void main(String[] args) {
        ImageLoader imageLoader = new ImageLoaderProxy("image.jpg", "admin");
        imageLoader.displayImage();

        ImageLoader imageLoader2 = new ImageLoaderProxy("image.jpg", "user");
        imageLoader2.displayImage();
    }
}

6 典型应用场景

代理模式在软件开发中有许多典型的应用场景,包括但不限于:

虚拟代理(Virtual Proxy):延迟加载。用于延迟加载大型资源,例如图像或文件,以提高性能。虚拟代理只在需要时加载真实对象,而不是在初始化时加载。

远程代理(Remote Proxy):远程服务访问。用于通过网络访问远程对象,隐藏了底层的网络通信细节。客户端可以像调用本地对象一样访问远程对象。

保护代理(Protection Proxy):权限控制。用于控制对对象的访问,确保只有合适的用户或客户端可以访问真实对象。通常用于实现身份验证和授权。

缓存代理(Cache Proxy):缓存管理。用于在访问对象之前检查缓存,以提高性能。如果请求的数据已存在于缓存中,代理会返回缓存的数据而不是重新加载。

日志记录代理(Logging Proxy):用于在调用真实对象的方法前后添加日志记录,以监控和记录系统行为。

动态代理(Dynamic Proxy):运行时代理。用于在运行时创建代理对象,通常通过Java的反射机制实现。动态代理可以实现通用的代理逻辑,而不需要为每个接口或对象单独创建代理类。

这些应用场景和功能分类展示了代理模式的灵活性和多样性。根据具体的需求和情况,可以选择使用代理模式的不同变体来实现所需的功能,从而提高代码的可维护性和灵活性

7 优缺点

优点:
控制访问:代理模式允许你控制对真实对象的访问,可以添加额外的逻辑来满足特定需求,如权限控制、日志记录等。

提高性能:虚拟代理和缓存代理可以提高性能,延迟加载和缓存对象可以减少不必要的资源消耗。

松耦合:代理模式可以将客户端与真实对象解耦,客户端不需要直接访问真实对象,从而降低了耦合度。

安全性:代理模式可以用于实现安全性控制,确保只有符合条件的用户或客户端可以访问真实对象。
缺点:
复杂性增加:引入代理对象可能会增加代码复杂性,特别是在涉及多个代理层的情况下。

性能开销:在一些情况下,代理模式可能引入性能开销,特别是在创建代理对象的开销较大时。

8 类似模式

与代理模式类似的模式包括装饰器模式和适配器模式。这些模式与代理模式有一些相似之处,但它们各自有不同的目的和应用场景。

装饰器模式(Decorator Pattern)

装饰器模式的主要目的是动态地为对象添加额外的功能,而不改变其接口。它通过将对象包装在装饰器类中来实现这一点。代理模式和装饰器模式都允许你包装对象并添加额外的功能。它们都通过组合实现,都有一个共同的接口,但其关注点不同。代理模式关注于控制访问和添加额外逻辑,而装饰器模式关注于动态添加功能,但不改变接口。

适配器模式(Adapter Pattern)

适配器模式的主要目的是将一个接口转换为另一个接口,以便两个不兼容的接口可以协同工作。它通常涉及到两个已存在的接口之间的适配。代理模式和适配器模式都涉及到包装对象。然而,代理模式主要关注于控制对真实对象的访问,而适配器模式主要关注于接口的转换。

9 小结

代理模式是一种有用的设计模式,用于控制对真实对象的访问并添加额外的功能。它在许多应用场景中都有广泛的用途,包括权限控制、延迟加载、性能优化等。通过引入代理对象,可以实现松耦合的设计,使系统更加灵活和可维护。然而,代理模式也需要谨慎使用,因为不当使用可能会引入复杂性和性能开销。在实际开发中,要根据具体需求和场景来选择是否使用代理模式以及何种类型的代理模式。希望本文能够帮助你更好地理解代理模式的概念和应用。

内容
  • RocketMQ消费者是如何负载均衡的
    RocketMQ消费者是如何负载
    2023-12-09
    摘要:RocketMQ 支持两种消息模式:集群消费( Clustering )和广播消费( Broadcasting )
  • FlashDuty Changelog 2023-09-07 | 新增深色模式与主题配置
    FlashDuty Change
    2023-12-04
    FlashDuty:一站式告警响应平台,前往此地址免费体验!.FlashDuty.现在已经全面支持了深色模式,这为您提供
  • git 配置代理  >_>从此告别git clone几KiB/s了
    git 配置代理 >_>从此告
    2023-12-02
    windows 设置代理.http || https协议.//设置全局代理.//http.git config --gl
  • 代码管理工具git的使用
    代码管理工具git的使用
    2023-12-01
    1. git 概述.git是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。也是Linu
  • 牛仔裤
    牛仔裤
    2024-01-05
    牛仔裤.牛仔裤,是一种起源于美国的经典服装单品,以其耐穿耐磨的特性,成为了时尚界不可或缺的一部分。无论是男女老少,都能在
  • 儿童T恤
    儿童T恤
    2023-12-26
    儿童T恤.儿童T恤是一种专门为儿童设计的上衣,具有舒适、时尚、环保等特点,是孩子们*常穿着的必备单品。.产品功能.儿童T
  • 婴儿连体衣
    婴儿连体衣
    2023-12-21
    婴儿连体衣.产品描述.婴儿连体衣是专门为婴儿设计的一款便捷舒适的睡衣,它将上衣和裤子融为一体,令宝宝在睡觉及活动时更加方
  • 外套
    外套
    2023-12-06
    外套.外套是一种经典的服装单品,不仅给人温暖的保护,还可以提升整体的时尚感。我们的外套采用高品质的材料和工艺**而成,既
  • 皮鞋
    皮鞋
    2024-01-15
    皮鞋.产品介绍.我们的皮鞋是经过精心设计和**的高品质鞋类产品。采用优质皮革和精湛工艺,为您提供舒适的穿着体验和时尚的外
  • 女童连衣裙
    女童连衣裙
    2024-01-15
    女童连衣裙.产品功能.高品质面料:选用优质的面料,柔软舒适,给孩子最佳的穿着体验.精美设计:精致的工艺和设计,展现孩子的
  • 儿童外套
    儿童外套
    2023-12-06
    儿童外套.产品功能.我们的儿童外套具有多种功能,包括保暖、防风、防水和舒适。它们采用高质量的面料制成,能够有效地抵御寒冷
  • 休闲鞋
    休闲鞋
    2024-01-05
    休闲鞋 - 轻松舒适的时尚选择.产品功能.休闲鞋 是一款适合各种活动的多功能鞋,其设计灵感来源于慢生活和自由精神。采用轻
  • 裤子
    裤子
    2023-12-26
    时尚新品发布:舒适时尚的裤子.产品功能.高品质的面料:采用柔软舒适的面料,透气性好,穿着舒适,不易起皱,易于护理。.人性
  • 儿童运动服
    儿童运动服
    2023-12-16
    儿童运动服.产品功能.我们的儿童运动服采用高品质的面料和工艺制作而成,具有出色的透气性和舒适性,可以让孩子在运动中保持干