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

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

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()方法,最终完成购物流程。

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

相关文章
|
22小时前
|
设计模式 缓存 JavaScript
js设计模式【详解】—— 代理模式
js设计模式【详解】—— 代理模式
6 0
|
4天前
|
设计模式 监控 安全
设计模式之代理模式(Java)
设计模式之代理模式(Java)
|
4天前
|
设计模式 安全 Java
Java设计模式:代理模式的静态和动态之分(八)
Java设计模式:代理模式的静态和动态之分(八)
|
4天前
|
设计模式 存储 SQL
设计模式——结构型模式(适配器,桥接,过滤器,组合,装饰器,外观,享元,代理)(2)
设计模式——结构型模式(适配器,桥接,过滤器,组合,装饰器,外观,享元,代理)
|
4天前
|
设计模式 存储 前端开发
设计模式——结构型模式(适配器,桥接,过滤器,组合,装饰器,外观,享元,代理)(1)
设计模式——结构型模式(适配器,桥接,过滤器,组合,装饰器,外观,享元,代理)
|
4天前
|
设计模式 JavaScript 前端开发
JavaScript设计模式——代理模式
JavaScript设计模式——代理模式
|
6天前
|
设计模式 Java
Java设计模式之代理模式详解
Java设计模式之代理模式详解
|
7天前
|
设计模式
代理模式-大话设计模式
代理模式-大话设计模式
4 0
|
12天前
|
设计模式 编解码 网络安全
结构型设计模式之代理模式
结构型设计模式之代理模式
|
12天前
|
设计模式
设计模式之结构型模式
设计模式之结构型模式