结构型模式

适配器模式

内容:将一个类的接口转换成客户希望的另一个接口。适配器模式使
得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
两种实现方式:
类适配器:使用多继承
对象适配器:使用组合

角色:
目标接口(Target)
待适配的类(Adaptee)
适配器(Adapter)
适用场景:
想使用一个已经存在的类,而它的接口不符合你的要求(对象适配器)想使用一些已经存在的子类,但不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。

from abc import ABCMeta, abstractmethod

class Payment(metaclass=ABCMeta):
# abstract class
@abstractmethod
def pay(self, money):
pass class 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 NewBankPay(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) # 组合 # class A:
# pass
#
# class B:
# def __init__(self):
# self.a = A()

  

桥模式

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

角色:
抽象(Abstraction)
细化抽象(RefinedAbstraction)
实现者(Implementor)
具体实现者(ConcreteImplementor)

应用场景:
当事物有两个维度上的表现,两个维度都可能扩展时。
优点:
抽象和实现相分离
优秀的扩展能力

from abc import ABCMeta, abstractmethod

class Shape(metaclass=ABCMeta):
def __init__(self, color):
self.color = color
@abstractmethod
def draw(self):
pass class Color(metaclass=ABCMeta):
@abstractmethod
def paint(self, shape):
pass class Rectangle(Shape):
name = "长方形"
def draw(self):
# 长方形逻辑
self.color.paint(self) class Circle(Shape):
name = "圆形"
def draw(self):
# 圆形逻辑
self.color.paint(self) # 调用color 对象的paint并把self形状对象传过去,方便color的paint打印 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()) # 先把color对象传过来,以便draw调用
# (其实draw调用的时候,是调用color的paint方法,并把shape对象传给paint让它去调用shape的name)
shape2.draw() # 两个维度都可以扩展

  

组合模式

内容:将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
角色:
抽象组件(Component)
叶子组件(Leaf)
复合组件(Composite)
客户端(Client)

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() """
------复合图形------
------复合图形------
点(2, 3)
线段[点(3, 4), 点(6, 7)]
线段[点(1, 5), 点(2, 8)]
------复合图形------
------复合图形------
点(4, 4)
线段[点(1, 1), 点(0, 0)]
------复合图形------
------复合图形------
"""

  

适用场景:
表示对象的“部分-整体”层次结构(特别是结构是递归的)
希望用户忽略组合对象与单个对象的不同,用户统一地使用组合结构中的所有对象
优点:
定义了包含基本对象和组合对象的类层次结构
简化客户端代码,即客户端可以一致地使用组合对象和单个对象
更容易增加新类型的组件

外观模式

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

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: # Facade
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()

  

优点:
减少系统相互依赖
提高了灵活性
提高了安全性

代理模式

内容:为其他对象提供一种代理以控制对这个对象的访问。
应用场景:
远程代理:为远程的对象提供代理
虚代理:根据需要创建很大的对象
保护代理:控制对原始对象的访问,用于对象有不同访问权限时

from abc import ABCMeta, abstractmethod

class Subject(metaclass=ABCMeta):
@abstractmethod
def get_content(self):
pass @abstractmethod
def set_content(self, content):
pass class RealSubject(Subject):
def __init__(self, filename):
self.filename = filename
with open(filename, 'r', encoding='utf-8') as f:
print("读取文件内容")
self.content = f.read() def get_content(self):
return self.content def set_content(self, content):
with open(self.filename, 'w', encoding='utf-8') as f:
f.write(content) 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) # 在调用get_content 时才真正去打开文件
return self.subj.get_content() def set_content(self, content):
if not 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 = RealSubject("test.txt")
#subj.get_content() subj = ProtectedProxy("test.txt")
print(subj.get_content())
# subj.set_content("abc")

  

角色:
抽象实体(Subject)
实体(RealSubject)
代理(Proxy)
优点:
远程代理:可以隐藏对象位于远程地址空间的事实
虚代理:可以进行优化,例如根据要求创建对象
保护代理:允许在访问一个对象时有一些附加的内务处理

sjms-3 结构型模式的更多相关文章

  1. Java设计模式之结构型模式

    结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 一.适配器模式: 意图: 将一个类的接口转换成客户希望的另外一个接口.Adapter 模式使得原本由于接 ...

  2. 代理模式/proxy模式/结构型模式

    代理模式proxy 定义 为其他对象提供一种代理,并以控制对这个对象的访问.最简单的理解,买东西都是要去商店的,不会去工厂. java实现三要素 proxy(代理)+subject(接口)+realS ...

  3. 第27章 结构型模式大PK

    27.1 代理模式 VS 装饰模式 27.1.1 代理模式 (1)场景:客人找运动员代理要求安排运动员参加比赛 (2)说明:代理人有控制权,可以拒绝客人的要求,也可以答应安排,甚至自己下去跑(因为有些 ...

  4. 设计模式之美:Structural Patterns(结构型模式)

    结构型模式涉及到如何组合类和对象以获得更大的结构. 结构型类模式采用继承机制来组合接口实现. 结构型对象模式不是对接口和实现进行组合,而是描述了如何对一些对象进行组合,从而实现新功能的一些方法. 因为 ...

  5. .NET设计模式(15):结构型模式专题总结(转)

    摘要:结构型模式,顾名思义讨论的是类和对象的结构,它采用继承机制来组合接口或实现(类结构型模式),或者通过组合一些对象,从而实现新的功能(对象结构型模式).这些结构型模式,它们在某些方面具有很大的相似 ...

  6. Java 23种设计模式详尽分析与实例解析之二--结构型模式

    Java设计模式 结构型模式 适配器模式 模式动机:在软件开发中采用类似于电源适配器的设计和编码技巧被称为适配器模式.通常情况下,客户端可以通过目标类的接口访问它所提供的服务.又是,现有的类可以满足客 ...

  7. Java经典23种设计模式之结构型模式(一)

    结构型模式包含7种:适配器模式.桥接模式.组合模式.装饰模式.外观模式.享元模式.代理模式. 本文主要介绍适配器模式和桥接模式. 一.适配器模式(Adapter) 适配器模式事实上非常easy.就像手 ...

  8. 设计模式(十二): Flyweight享元模式 -- 结构型模式

    说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释放.我们只是为了学习而简单做了介绍. 1. 概述 面 ...

  9. OOAD-设计模式(四)结构型模式之适配器、装饰器、代理模式

    前言 前面我们学习了创建型设计模式,其中有5中,个人感觉比较重要的是工厂方法模式.单例模式.原型模式.接下来我将分享的是结构型模式! 一.适配器模式 1.1.适配器模式概述 适配器模式(Adapter ...

  10. Java经典设计模式之七大结构型模式(附实例和详解)

    博主在大三的时候有上过设计模式这一门课,但是当时很多都基本没有听懂,重点是也没有细听,因为觉得没什么卵用,硬是要搞那么复杂干嘛.因此设计模式建议工作半年以上的猿友阅读起来才会理解的比较深刻.当然,你没 ...

随机推荐

  1. tabpanel如何隐藏页签表头以及基本用法总结

    tabpanel是extjs中一种比较常用的布局容器控件,也比较简单. ///1:相关的插件, var tabScrollerMenu = Ext.create("Ext.ux.TabScr ...

  2. C 语言 字符串命令 strstr()的用法 实现将原字符串以分割串分割输出

    C 语言 字符串命令 strstr()的用法 实现将原字符串以分割串分割输出 strstr() 命令是在原字符串中查找指定的字符串第一次出现的地址,用这个特性可以实现字符的分割,判断是否包涵等功能: ...

  3. splice() 方法通过删除现有元素和/或添加新元素来更改一个数组的内容。

    var myFish = ["angel", "clown", "mandarin", "surgeon"]; //从第 ...

  4. MemoryStream说明

    MemoryStream 是内存流,为系统内存提供读写操作,由于 MemoryStream 是通过无符号字节数组组成的,可以说 MemoryStream 的性能可以算比较出色,所以它担当起了一些其他流 ...

  5. c3p0数据源的第一次尝试

    开始补习 以前学习过的基础 正在尝试从c3p0 获取到connection 好的,首先上代码吧 public static DataSource ds = null; static { ComboPo ...

  6. DIV+CSS详解

    DIV+CSS详解 ✪DIV+CSS"这种叫法其实是一种不准确的叫法 在做笔记的最前面必须先给大家纠正一个错误,就是"DIV+CSS"这种叫法其实是一种不准确的叫法,是国 ...

  7. 100-days: twenty-seven

    Title: Criticism for China's child modeling(代指从事模特行业的人) industry after video of 3-year-old being kic ...

  8. mysql数据库优化之 如何选择合适的列建立索引

    1. 在where 从句,group by 从句,order by 从句,on 从句中出现的列: 2. 索引字段越小越好: 3. 离散度大的列放到联合索引的前面:比如: select * from p ...

  9. python—查找以XXX结尾的文件

    # 查找电脑所有视频 for cur_dir,dirs,files in os.walk(r'f:'): print('当前正在%s目录下查找'%cur_dir) for f in files:#当前 ...

  10. rancher的微服务运维

    1.安装rancher: rancher官网:https://rancher.com rancher中文官网:https://www.cnrancher.com rancher 2.0 文档:http ...