博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式二:结构型模式
阅读量:6163 次
发布时间:2019-06-21

本文共 6033 字,大约阅读时间需要 20 分钟。


结构型模式(7)种:适配器模式,桥模式,组合模式,装饰模式,外观模式,享元模式,代理模式

1、适配器模式

内容:将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

两种实现方式:

  • 类适配器:使用多继承
  • 对象适配器:使用组合 

角色:

  1、目标接口(target)

  2、待适配的类(Adaptee)

  3、适配器(Adapter)

适用场景:

  想使用一个已经存在的类,而它的接口不符合你的要求

  (对象适配器)想使用一些已经存在的子类,但不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。

from abc import ABCMeta, abstractmethodclass Payment(metaclass=ABCMeta):    # abstract class    @abstractmethod    def pay(self, money):        passclass Alipay(Payment):    def pay(self, money):        print("支付宝支付%d元." % money)class WechatPay(Payment):    def pay(self, money):        print("微信支付%d元." % money)class BankPay:    def cost(self, money):        print("银联支付%d元." % money)class ApplePay:    def cost(self, money):        print("苹果支付%d元." % money)# 类适配器# class PaymentAdapter(Payment, BankPay):#     def pay(self, money):#         self.cost(money)# 对象适配器class PaymentAdapter(Payment):    def __init__(self, payment):        self.payment = payment    def pay(self, money):        self.payment.cost(money)p = PaymentAdapter(BankPay())p.pay(100)## 目标接口:Payment 待适配的类:BankPay, ApplePay 适配器:PaymentAdapter
View Code

 

2、桥模式

内容:将一个事物的两个维度分离,使其都可以独立地变化。

角色:

  • 抽象(Abstraction)
  • 细化抽象(RefinedAbstraction)
  • 实现者(Implementor)
  • 具体实现者(ConcreteImplementor)

应用场景:当事物有两个维度上的表现,两个维度都有可能扩展时。

优点:

  • 抽象和实现相分离
  • 优秀的扩展能力
from abc import ABCMeta, abstractmethodclass Shape(metaclass=ABCMeta):    def __init__(self, color):        self.color = color    @abstractmethod    def draw(self):        passclass Color(metaclass=ABCMeta):    @abstractmethod    def paint(self, shape):        passclass Rectangle(Shape):    name = "长方形"    def draw(self):        # 长方形逻辑        self.color.paint(self)class Circle(Shape):    name = "圆形"    def draw(self):        # 圆形逻辑        self.color.paint(self)class Line(Shape):    name = "直线"    def draw(self):        # 直线逻辑        self.color.paint(self)class Red(Color):    def paint(self, shape):        print("红色的%s" % shape.name)class Green(Color):    def paint(self, shape):        print("绿色的%s" % shape.name)class Blue(Color):    def paint(self, shape):        print("蓝色的%s" % shape.name)                shape = Line(Blue())shape.draw()shape2 = Circle(Green())shape2.draw()##    抽象:Shape    细化抽象:Color    实现者:Red,Green,Blue    具体实现者:Rectangle,Circle, Line
View Code

 

3、组合模式

内容:将对象组合成树型结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

角色:

  • 抽象组件(Component)
  • 叶子组件(Leaf)
  • 复合组件(Composite)
  • 客户端(Client)

适用场景:

  表示对象的"部分-整体"层次结构(特别是结构是递归的)

  希望用户忽略组合对象与单个对象的不同,用户统一地适用组合结构中的所有对象。

优点:

  1. 定义了包含基本对象和组合对象的层次结构
  2. 简化客户端代码,即客户端可以一直地使用组合对象和单个对象
  3. 更容易增加新类型的组件
from abc import ABCMeta, abstractmethod# 抽象组件class Graphic(metaclass=ABCMeta):    @abstractmethod    def draw(self):        pass# 叶子组件class Point(Graphic):    def __init__(self, x, y):        self.x = x        self.y = y    def __str__(self):        return "点(%s, %s)" % (self.x, self.y)    def draw(self):        print(str(self))# 叶子组件class Line(Graphic):    def __init__(self, p1, p2):        self.p1 = p1        self.p2 = p2    def __str__(self):        return "线段[%s, %s]" % (self.p1, self.p2)    def draw(self):        print(str(self))# 复合组件class Picture(Graphic):    def __init__(self, iterable):        self.children = []        for g in iterable:            self.add(g)    def add(self, graphic):        self.children.append(graphic)    def draw(self):        print("------复合图形------")        for g in self.children:            g.draw()        print("------复合图形------")p1 = Point(2,3)l1 = Line(Point(3,4), Point(6,7))l2 = Line(Point(1,5), Point(2,8))pic1 = Picture([p1, l1, l2])p2 = Point(4,4)l3 = Line(Point(1,1), Point(0,0))pic2 = Picture([p2, l3])pic = Picture([pic1, pic2])pic.draw()
View Code

 

4、外观模式

内容:为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

角色:

  • 外观(facade)
  • 子系统类(subsystem classes)

优点:

  1. 减少系统相互依赖
  2. 提高了灵活性
  3. 提高了安全性
class CPU:    def run(self):        print("CPU开始运行")    def stop(self):        print("CPU停止运行")class Disk:    def run(self):        print("硬盘开始工作")    def stop(self):        print("硬盘停止工作")class Memory:    def run(self):        print("内存通电")    def stop(self):        print("内存断电")class Computer:    def __init__(self):        self.cpu = CPU()        self.disk = Disk()        self.memory = Memory()            def run(self):        self.cpu.run()        self.disk.run()        self.memory.run()    def stop(self):        self.cpu.stop()        self.disk.stop()        self.memory.stop()computer = Computer()computer.run()computer.stop()
View Code

 

5、代理模式

内容:为其他对象提供一种代理以控制对这个对象的访问。

应用场景:

  • 远程代理:为远程的对象提供代理
  • 虚代理:根据需要创建很大的对象
  • 保护代理:控制对原始对象的访问,用于对象有不同访问权限时

角色:

  抽象实体(Subject)

  实体(Realsubject)

  代理(Proxy)

优点:

  • 远程代理:可以隐藏对象位于远程地址空间的事实
  • 虚代理:可以进行优化,例如可以根据需求创建对象
  • 保护代理:允许在访问一个对象时有一些附加的内务处理
from abc import ABCMeta, abstractmethodclass Subject(metaclass=ABCMeta):    @abstractmethod    def get_content(self):        pass    @abstractmethod    def set_content(self, content):        passclass RealSubject(Subject):    def __init__(self, filename):        self.filename = filename        f = open(filename, 'r', encoding="utf-8")        print("读取文件内容")        self.content = f.read()        f.close()    def get_content(self):        return self.content    def set_content(self, content):        f = open(self.filename, 'w', encoding="utf-8")        f.write(content)        f.close()class VirtualProxy(Subject):    def __init__(self, filename):        self.filename = filename        self.subj = None    def get_content(self):        if not self.subj:            self.subj = RealSubject(self.filename)        return self.subj.get_content()    def set_content(self, content):        if not self.subj:            self.subj = RealSubject(self.filename)        return self.subj.set_content(content)class ProtectedProxy(Subject):    def __init__(self, filename):        self.subj = RealSubject(filename)    def get_content(self):        return self.subj.get_content()    def set_content(self, content):        raise PermissionError("无写入权限")subj = ProtectedProxy("test.txt")print(subj.get_content())subj.set_content("abc")
View Code

 

转载于:https://www.cnblogs.com/Xuuuuuu/p/10861657.html

你可能感兴趣的文章
分析jQuery源码时记录的一点感悟
查看>>
程序局部性原理感悟
查看>>
UIView 动画进阶
查看>>
Spring如何处理线程并发
查看>>
linux常用命令(用户篇)
查看>>
获取组件的方式(方法)
查看>>
win2008 server_R2 自动关机 解决
查看>>
我的友情链接
查看>>
在C#调用C++的DLL简析(二)—— 生成托管dll
查看>>
Linux macos 常用终端操作
查看>>
企业网络的管理思路
查看>>
Linux磁盘分区与挂载
查看>>
J2se学习笔记一
查看>>
DNS视图及日志系统
查看>>
老李分享:Android性能优化之内存泄漏 3
查看>>
mysql命令
查看>>
来自极客标签10款最新设计素材-系列七
查看>>
极客技术专题【009期】:web技术开发小技巧
查看>>
PHP 简单计算器代码实现
查看>>
正则表达式的知识普及
查看>>