ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Python设计模式之代理模式

2019-06-27 18:51:46  阅读:186  来源: 互联网

标签:__ Python pay self 代理 card 设计模式 def


代理模式目录

代理模式

概念

  • 代理就是一个中间系统
  • 代理模式关键在于对外屏蔽真实对象
  • 通过代购可以类比一下

演员与经纪人的例子来理解一下:

class Actor(object):
    def __init__(self):
        self.is_busy = False

    def occupied(self):
        self.is_busy = True
        print(type(self).__name__, '正在拍电影')

    def available(self):
        self.is_busy = False
        print(type(self).__name__, '正在休息')

    def get_status(self):
        return self.is_busy

class Agent(object):
    def __init__(self):
        self.principal = None

    def work(self):
        # 给他一个演员
        self.actor = Actor()
        # 如果在忙就休息,如果在休息就忙起来
        if self.actor.get_status():
            self.actor.occupied()
        else:
            self.actor.available()

代理维护一个引用,代理通过这个引用访问实际对象。代理也负责创建和删除真实业务。


实现:

再来一个例子实现一个规模较大的代理:
付款系统

  • 用户行为由类User表示
  • 为了购买衣服,User类提供pay方法
  • 魔法方法__init__调用代理并将其实例化
  • pay方法在内部调用代理的方法进行付款
  • 付款成功,返回__del__方法
class User(object):
    def __init__(self):
        self.debit_card = DebitCard()
        self.is_purchased = None

    def pay(self, card_id):
        self.is_purchased = self.debit_card.do_pay(card_id)

    def __del__(self):
        if self.is_purchased:
            print('购买成功')
        else:
            print('购买失败')


# 主题是付款,是一个抽象基类,
from abc import ABCMeta, abstractmethod
class Payment(metaclass=ABCMeta):
    @abstractmethod
    def do_pay(self):
        pass


# 真实主题银行类
class Bank(Payment):
    def __init__(self):
        self.card = None
        self.account = None

    def __get_acount(self):
        self.account = self.card
        return self.account

    def __has_funds(self):
        print('找到卡号:', self.__get_acount())
        return True

    def set_card(self, card):
        self.card = card

    def do_pay(self):
        if self.__has_funds():
            print('扣款成功')
            return True
        else:
            print('扣款失败')
            return False


# 代理
class DebitCard(Payment):
    def __init__(self):
        self.bank = Bank()

    def do_pay(self, card_id):
        self.bank.set_card(card_id)
        return self.bank.do_pay()


user = User()
user.pay('123456')

代理有什么用?

  • 代理可以通过缓存要频繁访问的对象来提高性能
  • 可以比作:代购

代理和门面区别

代理模式 门面模式
给其他对象提供了代理或者占位符,以控制对原始对象的访问 为大型子系统提供接口
代理对象和目标对象接口一致,并有对目标的引用 实现子系统之间通信和依赖的最小化
充当客户端和被封装对象的中介 提供单一的简单的接口

常见问题

  • 装饰器和代理区别:
    • 装饰器给正在运行时的对象添加行为,代理是控制对象的访问。代理不是动态的,装饰器是动态的。
  • 代理模式缺点:
    • 增加响应时间,比如代理如果结构不好,就会增加时间。所以取决于代理写的好不好
  • 客户端可以独立访问真实主题吗?
    • 可以,但是代理模式可以提供许多优势:虚拟、远程等。
  • 代理能给自己添加功能吗?
    • 可以,而且无需改对象的代码。代理和真是主题可以实现相同的接口

标签:__,Python,pay,self,代理,card,设计模式,def
来源: https://blog.csdn.net/likunkun__/article/details/93894907

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有