Posts 设计模式-代理模式
Post
Cancel

设计模式-代理模式

概念解析

代理模式,指的是对象完成某项动作或任务,是通过对另一个对象的引用来完成的,即“为其他对象提供一个代理以控制这个对象的访问”。其英文称为”Proxy”或”Surrogate”,其核心思想为:

  • 使用一个额外的间接层来支持分散的、可控的、智能的访问
  • 增加一个包装和委托来保护真正的组件,以避免过度复杂

设计过程中包含三个核心角色:

  • Subject:定义操作、活动、任务的接口类
  • RealSubject:真正完成操作、活动、任务的具体类
  • ProxySubject:代替真实主题完成操作、活动、任务的代理类

代理模式类图如下:

img

优点:

  • 代理模式能够协调调用者和被调用者,在一定程度上降低系统的耦合度
  • 可以灵活地隐藏被代理对象的部分功能和服务,也可以增加额外的功能和服务

缺点:

  • 增加了额外的代理对象,但是添加的代理可能会造成请求的处理变慢
  • 实现代理需要额外的工作,有些代理的实现非常复杂

适用的一些场景:

  • 移动端进行网页加载图片的时候,如果加载原图比较耗费流量,影响性能;可以采用小图进行代替渲染:采用代理对象去下载小图,而在真正点击图片下载的时候,才会下载大图,显示大图效果。
  • 其他特殊用途的代理:远程代理、虚拟代理、保护代理、防火墙代理、同步化代理、智能引用代理、同步化代理、智能引用代理。

设计模板

基本设计模板如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
from abc import ABCMeta, abstractmethod
# 引入ABCMeta和abstractmethod来定义抽象类和抽象方法

class Subject(metaclass=ABCMeta):
    """主题类"""
    def __init__(self, name):
        self.__name = name

    def get_name(self):
        return self.__name

    @abstractmethod
    def request(self, content = ''):
        pass


class RealSubject(Subject):
    """真实主题类"""
    def request(self, content):
        print("RealSubject todo something...")


class ProxySubject(Subject):
    """代理主题类"""
    def __init__(self, name, subject):
        super().__init__(name)
        self._real_subject = subject

    def request(self, content = ''):
        self.pre_request()
        if self._real_subject is not None:
            self._real_subject(content)
        self.after_request()

    def pre_request(self):
        print("Pre request to do something...")

    def after_request(self):
        print("After request to do something...")


def testProxy():
    real_obj = RealSubject('RealSubject')
    proxy_obj = ProxySubject('ProxySubject', read_obj)
    proxy_obj.request()
    """
    输出结果:
    Pre request to do something...
    RealSubject todo something...
    After request to do something...
    """

实例分析

实例说明:快递代收机制,可以本人获取也可以他人通过凭证进行代收:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class TonyRecption(Subject):
    """本人Tony签收"""
    def __init__(self, name, phone_num):
        super().__init__(name)
        self.__phone_num = phone_num

    def get_phone_num(self):
        return self.__phone_num

    def request(self, content):
        print("货物主人:%s,手机号:%s," % (self.get_name(), self.get_phone_num()))
        print("接受一个包裹,包裹内容:%s" % str(content))


class WendyReception(ProxySubject):
    """Wendy代收"""
    def __init__(self, name, receiver):
        super().__init__(name, receiver)

    def pre_request(self):
        print("我是%s的朋友,我来帮他代收快递!" % (self._realSubject.get_name()))

    def after_request(self):
        print("代收人:%s" % self.get_name())


def testReceiveParcel():
    tony = TonyReception("Tony", "12345678901")
    print("Tony接收:")
    tony.request("雪地靴")

    print("Wendy接收:")
    wendy = WendyReception("Wendy", tony)
    wendy.request("雪地靴")

    """
    测试结果:
    Tony接收:
    货物主人:Tony,手机号:12345678901
    接受一个包裹,包裹内容:雪地靴
    Wendy接收:
    我是Tony的朋友,我来帮他代收快递!
    货物主人:Tony,手机号:12345678901
    接受一个包裹,包裹内容:雪地靴
    代收人:Wendy
    """
This post is licensed under CC BY 4.0 by the author.

设计模式-外观模式

设计模式-备忘模式