设计模式-结构型模式:代理模式

简介: 设计模式-结构型模式:代理模式

1、简介

代理模式(Proxy Pattern)是一种结构型设计模式,其目的是在不改变原有代码的情况下,为其他对象提供一个代理,以控制对原有对象的访问。代理模式是一种非常常见的设计模式,其应用场景包括远程代理、虚拟代理、保护代理等。

2、组成部分

代理模式中包含以下角色:

  1. 抽象主题(Subject):定义了真实主题和代理主题的共同接口,这样在任何使用真实主题的地方都可以使用代理主题。
  2. 真实主题(Real Subject):定义了代理所代表的真实对象,是代理模式中被代理的对象。
  3. 代理(Proxy):持有对真实主题的引用,并在需要的时候创建真实主题对象,实现抽象主题接口,可以访问、控制和扩展真实主题对象。

3、优缺点

代理模式是一种常用的结构型设计模式,它允许你为其他对象提供一个代理或者占位符,以控制对原对象的访问。代理对象充当了原对象的接口,并且可以控制对原对象的访问。下面是代理模式的优点和缺点。

优点:

  1. 代理模式可以隐藏原对象的复杂性,客户端无需知道具体的实现细节,只需要与代理进行交互即可,从而简化了客户端代码。
  2. 代理模式可以提高系统的性能,特别是在访问远程对象或者具有大量资源的对象时,代理可以在必要的时候进行缓存,避免重复访问原对象,从而提高了系统的性能。
  3. 代理模式可以增强系统的安全性,例如可以控制对原对象的访问权限,防止非授权访问原对象。
  4. 代理模式可以实现远程方法调用,允许客户端通过网络访问远程对象的方法,从而实现分布式系统的开发。

缺点:

  1. 代理模式可能会导致系统变得更加复杂,因为它需要额外的类来实现代理,增加了系统的复杂度。
  2. 代理模式可能会降低系统的性能,因为每次访问原对象都需要经过代理,从而增加了额外的开销。
  3. 代理模式需要为每一个原对象实现一个代理类,如果原对象很多,就需要实现很多代理类,这可能会使代码变得难以维护。

总的来说,代理模式是一种非常有用的设计模式,可以帮助我们实现许多有趣的功能和增强系统的安全性。但是,在使用代理模式时需要权衡其优缺点,根据具体的需求和情况选择是否使用代理模式。

4、使用场景

代理模式是一种常用的结构型设计模式,它通常用于以下几种场景:

  1. 远程代理:代理模式最常见的应用场景就是远程代理。当我们需要访问远程对象时,可以使用代理对象来实现远程访问,避免直接访问远程对象带来的效率和安全性问题。远程代理可以隐藏远程对象的实现细节,提供与本地对象类似的接口,并且可以在必要的时候进行缓存,以提高系统的性能。
  2. 虚拟代理:虚拟代理通常用于延迟加载。当我们需要访问一个耗时的对象时,可以使用虚拟代理来延迟加载该对象。在访问虚拟代理时,代理会先检查该对象是否已经被加载,如果没有加载,则会先加载该对象,然后再将访问请求转发给实际对象。
  3. 安全代理:安全代理通常用于控制对对象的访问权限。当我们需要限制对某个对象的访问权限时,可以使用安全代理来限制对该对象的访问。安全代理可以检查客户端是否具有足够的权限来访问该对象,如果没有权限,则会拒绝访问。
  4. 智能代理:智能代理通常用于在访问对象前后添加额外的逻辑。当我们需要在访问对象前后执行一些额外的逻辑时,可以使用智能代理来添加该逻辑。智能代理可以在访问对象前后执行一些额外的逻辑,例如记录日志、统计访问次数、实现事务等。
  5. 缓存代理:缓存代理通常用于缓存对象的访问结果,避免重复计算。当我们需要频繁访问某个对象时,可以使用缓存代理来缓存该对象的访问结果。在访问缓存代理时,代理会先检查缓存中是否已经有该对象的访问结果,如果有,则直接返回缓存的结果,否则会计算该对象的访问结果,并将结果缓存起来。

总的来说,代理模式可以帮助我们实现许多有趣的功能,例如远程访问、延迟加载、访问控制、性能优化等。在实际应用中,我们需要根据具体的需求和情况选择适合的代理模式,并结合其他设计模式来实现更加复杂的功能。

5、代码实现

代理模式的结构通常包括三个部分:

  1. 抽象主题角色(Subject):定义代理类和真实主题类的共同接口。
  2. 真实主题角色(RealSubject):定义代理类所代表的真实对象,是我们最终想要访问的对象。
  3. 代理角色(Proxy):代理对象,维护一个对真实主题对象的引用,通过代理对象来间接访问真实主题对象。

5.1、Java

下面是一个简单的示例,我们以一个在线购物的场景为例,来演示如何使用代理模式。

1、定义抽象主题角色(Subject):

1. public interface Shopping {
2. void buy();
3. }

2、定义真实主题角色(RealSubject):

1. public class OnlineShopping implements Shopping {
2. @Override
3. public void buy() {
4.         System.out.println("购买商品");
5.     }
6. }

3、定义代理角色(Proxy):

1. public class ShoppingProxy implements Shopping {
2. private OnlineShopping onlineShopping;
3. 
4. public ShoppingProxy() {
5. this.onlineShopping = new OnlineShopping();
6.     }
7. 
8. @Override
9. public void buy() {
10.         beforeBuy();
11.         onlineShopping.buy();
12.         afterBuy();
13.     }
14. 
15. private void beforeBuy() {
16.         System.out.println("选择商品");
17.     }
18. 
19. private void afterBuy() {
20.         System.out.println("付款");
21.     }
22. }

在上面的代码中,我们定义了一个代理角色(ShoppingProxy),它维护了一个对真实主题对象(OnlineShopping)的引用。在代理对象的buy()方法中,我们首先执行了一些额外的逻辑(选择商品),然后再调用真实主题对象的buy()方法,最后再执行一些额外的逻辑(付款)。

4、 测试代理模式:

1. public class Test {
2. public static void main(String[] args) {
3. Shopping shopping = new ShoppingProxy();
4.         shopping.buy();
5.     }
6. }

在上面的代码中,我们创建了一个代理对象(ShoppingProxy),并调用了它的buy()方法。在调用buy()方法时,代理对象会执行一些额外的逻辑,然后再调用真实主题对象(OnlineShopping)的buy()方法,最终完成购物流程。

代理模式的优点在前面已经进行了介绍,这里不再赘述。需要注意的是,代理模式也有一些缺点,例如代理模式会增加系统的复杂性,增加了代码量和维护成本。在实际应用中,我们需要根据具体的需求和情况选择适合的设计模式。

5.2、python

下面我们将使用Python代码来演示如何实现代理模式,并作详细说明。

代理模式的结构通常包括三个部分:

  1. 抽象主题角色(Subject):定义代理类和真实主题类的共同接口。
  2. 真实主题角色(RealSubject):定义代理类所代表的真实对象,是我们最终想要访问的对象。
  3. 代理角色(Proxy):代理对象,维护一个对真实主题对象的引用,通过代理对象来间接访问真实主题对象。

下面是一个简单的示例,我们以一个在线购物的场景为例,来演示如何使用代理模式。

1、定义抽象主题角色(Subject):

1. from abc import ABC, abstractmethod
2. 
3. class Shopping(ABC):
4.     @abstractmethod
5. def buy(self):
6. pass

2、定义真实主题角色(RealSubject):

1. class OnlineShopping(Shopping):
2. def buy(self):
3. print("购买商品")

3、 定义代理角色(Proxy):

1. class ShoppingProxy(Shopping):
2. def __init__(self):
3.         self._online_shopping = OnlineShopping()
4. 
5. def buy(self):
6.         self.before_buy()
7.         self._online_shopping.buy()
8.         self.after_buy()
9. 
10. def before_buy(self):
11. print("选择商品")
12. 
13. def after_buy(self):
14. print("付款")

在上面的代码中,我们定义了一个代理角色(ShoppingProxy),它维护了一个对真实主题对象(OnlineShopping)的引用。在代理对象的buy()方法中,我们首先执行了一些额外的逻辑(选择商品),然后再调用真实主题对象的buy()方法,最后再执行一些额外的逻辑(付款)。

4、 测试代理模式:

1. if __name__ == "__main__":
2.     shopping = ShoppingProxy()
3.     shopping.buy()

在上面的代码中,我们创建了一个代理对象(ShoppingProxy),并调用了它的buy()方法。在调用buy()方法时,代理对象会执行一些额外的逻辑,然后再调用真实主题对象(OnlineShopping)的buy()方法,最终完成购物流程。

代理模式的优点在前面已经进行了介绍,这里不再赘述。需要注意的是,代理模式也有一些缺点,例如代理模式会增加系统的复杂性,增加了代码量和维护成本。在实际应用中,我们需要根据具体的需求和情况选择适合的设计模式。

相关文章
|
18天前
|
设计模式 缓存 Java
「全网最细 + 实战源码案例」设计模式——代理模式
代理模式(Proxy Pattern)是一种结构型设计模式,通过代理对象控制对目标对象的访问并添加额外功能。它分为静态代理和动态代理,后者包括JDK动态代理和CGLIB动态代理。JDK动态代理基于接口反射生成代理类,而CGLIB通过继承目标类生成子类。代理模式适用于延迟初始化、访问控制、远程服务、日志记录和缓存等场景,优点是职责分离、符合开闭原则和提高安全性,缺点是增加系统复杂性。
69 25
|
2月前
|
设计模式 前端开发 数据安全/隐私保护
前端必须掌握的设计模式——代理模式
代理模式(Proxy Pattern)是一种结构型设计模式,通过引入“替身”对象来间接访问真实对象,从而解耦并提升性能和安全性。例如,知名艺人复出后,经纪人作为代理筛选商单,确保只处理符合团队利益的请求。代码实现中,定义接口`IService`,艺人和经纪人都实现该接口,经纪人在访问时进行过滤和转发。代理模式常用于权限控制、性能优化等场景,如前端中的Tree-shaking和ES6的Proxy构造方法。
前端必须掌握的设计模式——代理模式
|
5月前
|
设计模式 缓存 安全
设计模式——代理模式
静态代理、JDK动态代理、Cglib 代理
设计模式——代理模式
|
5月前
|
设计模式 Java 数据安全/隐私保护
Java设计模式-代理模式(7)
Java设计模式-代理模式(7)
|
6月前
|
设计模式 存储 Java
【十】设计模式~~~结构型模式~~~享元模式(Java)
文章详细介绍了享元模式(Flyweight Pattern),这是一种对象结构型模式,通过共享技术实现大量细粒度对象的重用,区分内部状态和外部状态来减少内存中对象的数量,提高系统性能。通过围棋棋子的设计案例,展示了享元模式的动机、定义、结构、优点、缺点以及适用场景,并探讨了单纯享元模式和复合享元模式以及与其他模式的联用。
【十】设计模式~~~结构型模式~~~享元模式(Java)
|
6月前
|
设计模式 存储 Java
【九】设计模式~~~结构型模式~~~外观模式(Java)
文章详细介绍了外观模式(Facade Pattern),这是一种对象结构型模式,通过引入一个外观类来简化客户端与多个子系统之间的交互,降低系统的耦合度,并提供一个统一的高层接口来使用子系统。通过文件加密模块的实例,展示了外观模式的动机、定义、结构、优点、缺点以及适用场景,并讨论了如何通过引入抽象外观类来提高系统的可扩展性。
【九】设计模式~~~结构型模式~~~外观模式(Java)
|
6月前
|
设计模式 Java
【八】设计模式~~~结构型模式~~~装饰模式(Java)
文章详细介绍了装饰模式(Decorator Pattern),这是一种对象结构型模式,用于在不使用继承的情况下动态地给对象添加额外的职责。装饰模式通过关联机制,使用装饰器类来包装原有对象,并在运行时通过组合的方式扩展对象的行为。文章通过图形界面构件库的设计案例,展示了装饰模式的动机、定义、结构、优点、缺点以及适用场景,并提供了Java代码实现和应用示例。装饰模式提高了系统的灵活性和可扩展性,适用于需要动态、透明地扩展对象功能的情况。
【八】设计模式~~~结构型模式~~~装饰模式(Java)
|
6月前
|
设计模式 XML 存储
【七】设计模式~~~结构型模式~~~桥接模式(Java)
文章详细介绍了桥接模式(Bridge Pattern),这是一种对象结构型模式,用于将抽象部分与实现部分分离,使它们可以独立地变化。通过实际的软件开发案例,如跨平台视频播放器的设计,文章阐述了桥接模式的动机、定义、结构、优点、缺点以及适用场景,并提供了完整的代码实现和测试结果。桥接模式适用于存在两个独立变化维度的系统,可以提高系统的可扩展性和灵活性。
【七】设计模式~~~结构型模式~~~桥接模式(Java)
|
6月前
|
设计模式 XML 存储
【六】设计模式~~~结构型模式~~~适配器模式(Java)
文章详细介绍了适配器模式(Adapter Pattern),这是一种结构型设计模式,用于将一个类的接口转换成客户期望的另一个接口,使原本不兼容的接口能够一起工作,提高了类的复用性和系统的灵活性。通过对象适配器和类适配器两种实现方式,展示了适配器模式的代码应用,并讨论了其优点、缺点以及适用场景。
|
6月前
|
设计模式 缓存 Java
【十一】设计模式~~~结构型模式~~~代理模式(Java)
文章详细介绍了代理模式(Proxy Pattern),这是一种对象结构型模式,用于给对象提供一个代理以控制对它的访问。文中阐述了代理模式的动机、定义、结构、优点、缺点和适用环境,并探讨了远程代理、虚拟代理、保护代理等不同代理形式。通过一个商务信息查询系统的实例,展示了如何使用代理模式来增加身份验证和日志记录功能,同时保持客户端代码的无差别对待。此外,还讨论了代理模式在分布式技术和Spring AOP中的应用,以及动态代理的概念。
【十一】设计模式~~~结构型模式~~~代理模式(Java)

热门文章

最新文章