首页 > 其他分享 >4.结构型模式

4.结构型模式

时间:2024-03-26 21:44:34浏览次数:19  
标签:__ self 模式 content print class def 结构型

@

目录

1. 适配器模式

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

class A:
	pass
	
class B:
	def __init__():
		self.a = A()

类适配器模式使用示例:

# 类适配器模式使用示例:
from abc import ABCMeta, abstractmethod

# 目标接口
class Payment(object, metaclass=ABCMeta):
    @abstractmethod
    def pay(self, money):
        pass

class Alipay(Payment):
    def pay(self, money):
        print('支付了%d' % money)

# 待适配的类
class BankPay():
    def cost(self, money):
        print('银联支付了%d' % money)

# 类适配器
class PaymentAdapter(Payment, BankPay):
    """
    把不兼容cost转换成pay
    """

    def pay(self, money):
        self.cost(money)

p = PaymentAdapter()
p.pay(100)
"""
银联支付了100
"""

对象适配器模式使用示例:

# 类适配器模式使用示例:
from abc import ABCMeta, abstractmethod

# 目标接口
class Payment(object, metaclass=ABCMeta):
    @abstractmethod
    def pay(self, money):
        pass

class Alipay(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):
    def __init__(self, payment):
        self.payment = payment

    def pay(self, money):
        self.payment.cost(money)

p = PaymentAdapter(ApplePay())
p.pay(100)
p = PaymentAdapter(BankPay())
p.pay(100)
"""
苹果支付了100
银联支付了100
"""

      适配器模式有三种角色,分别是目标接口、待适配的类和适配器。适用场景是:想使用一个已存在的类,而它的接口不符合你的要求。想使用一些已经存在的类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。

2. 桥模式

      桥模式是将一个事物的两个维度分离,使其都可以独立地变化。当事物有两个维度的表现,两个维度都可能扩展时使用。优点是:抽象和实现相分离,扩展能力强。如果不使用桥模式,在任何维度进行扩展,需要改好多代码,因为使用到了继承:

class Shape:
	pass

class Rectangle(Shape):
	pass

class Circle(Shape):
	pass

class RedRectangle(Rectangle):
	pass

class GreenRectangle(Rectangle):
	pass
	
class RedCircle(Circle):
	pass

class GreenCircle(Circle):
	pass

      以上代码形状和颜色两个维度是通过类的继承关系紧密结合在一起,是紧耦合。紧耦合是是不可取的,应用桥模式的思想,可以使用组合来实现(松耦合)。如果需要画直线,直接加上直线的类。需要新颜色,直接加上颜色的类。两个维度都可以自由扩展,不需要添加很多代码。这里的角色有抽象、细化抽象、实现者和具体实现者:

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)

# 细化实现
class Red(Color):
    def paint(self, shape):
        print('画红色的%s' % shape.name)

# 如果要扩展颜色,只需要添加颜色类
class Green(Color):
    def paint(self, shape):
        print('画绿色的%s' % shape.name)

rectangle = Rectangle(Red())
rectangle.draw()
circle = Circle(Green())
circle.draw()
"""
画红色的长方形
画绿色的圆形
"""
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(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(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):
        for g in self.children:
            g.draw()

# 简单图形
print('------简单图形------')
p = Point(1, 2)
l1 = Line(Point(1, 2), Point(3, 4))
l2 = Line(Point(5, 6), Point(7, 8))
print(p)
print(l1)
print(l2)
print('------复合图形(p,l1,l2)------')
# 复合图形
pic = Picture([p, l1, l2])
pic.draw()
4. 外观模式

      外观模式为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层的接口,这个接口使得这一子系统更加容易使用。外观模式下的角色有外观和子系统类,优点是:减少系统相互依赖,提高灵活性,提高了安全性。下面看一个例子:

# 子系统类
class CPU:
    def run(self):
        print('CPU start to run...')

    def stop(self):
        print('CPU stop to run...')

# 子系统类
class Disk:
    def run(self):
        print('Disk start to run...')

    def stop(self):
        print('Disk stop to run...')

# 子系统类
class Memory:
    def run(self):
        print('Memory start to run...')

    def stop(self):
        print('Memory stop to run...')

# 外观
class Computer():
    def __init__(self):
        self.CPU = CPU()
        self.Disc = Disk()
        self.Member = Memory()

    def run(self):
        self.CPU.run()
        self.Disc.run()
        self.Member.run()

    def stop(self):
        self.CPU.stop()
        self.Disc.stop()
        self.Member.stop()

# 客户端,高层代码
c = Computer()
c.run()
c.stop()
5. 代理模式

      为其它对象提供一种代理以控制对这个对象的访问。角色有抽象实体、实体和代理。应用场景有远程代理:为远程的对象提供代理(通过ORM向数据库写值,不用关注数据库是在远程);虚代理:根据需要创建很大的对象(需要的时候创建对象);保护代理:控制对原始对象的访问,用于对象有不同的访问权限。下面是不使用虚代理的例子:

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
        print('读取文件内容!')
        with open(self.filename, 'r', encoding='utf-8') as f:
            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)

subj = RealSubject('test.txt')
"""
读取文件内容!
"""

使用虚代理的例子:

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
        print('读取文件内容!')
        with open(self.filename, 'r', encoding='utf-8') as f:
            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)
        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)

subj = VirtualProxy('test.txt')
print(subj.get_content())
"""
读取文件内容!
"""

      不使用虚代理,只要是实例化 RealSubject 类,就会读取这个文件占用内存。使用虚代理后,可以和根据需要创建对象,用户不调用是不会创建 RealSubject 对象的,节省了内存的开销。如果需要只有读的权限而没有写的权限,可以使用保护代理:

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
        print('读取文件内容!')
        with open(self.filename, 'r', encoding='utf-8') as f:
            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 ProtectedSubject(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 = ProtectedSubject('test.txt')
print(subj.get_content())
subj.set_content('abc')
"""
读取文件内容!
test file!
Traceback (most recent call last):
  File "/home/thanlon/projects/PycharmProjects/untitled/代理模式.py", line 42, in <module>
    subj.set_content('abc')
  File "/home/thanlon/projects/PycharmProjects/untitled/代理模式.py", line 37, in set_content
    raise PermissionError('无写入权限!')
PermissionError: 无写入权限!
"""

标签:__,self,模式,content,print,class,def,结构型
From: https://www.cnblogs.com/thankcat/p/18097665

相关文章

  • 工厂模式
     1.工厂模式介绍提供了一种将对象创建过程封装到一个单独的类中的方式,这个类就是被称为‘工厂类’,它根据特定的条件来决定应该创建哪个对象 2.工厂模式的创建方式(1)简单工厂模式publicinterfacePhone{/***抽象电话功能*/voidcall()......
  • Blazor学习记录六_模版化组件_渲染模式_CSS隔离和代码隔离
    17.模版化组件在组件中放置一个可渲染的代码片段供外部调用者来传入要渲染的内容及渲染样式,这样的组件就叫做模版化的组件。一般是一个支持泛型的组件,目标为消费者封装重复使用的通用性良好的UI组件。比如一个用来给用户呈现表格数据的表格组件。示例组件GenaricTable.razor代......
  • Redis发布订阅模式解决Guava Cache本地缓存刷新问题
    为什么要用本地缓存可以加快资源访问速度,减少第三方IO延迟,也避免了网络调用的开销,将数据存储在本地jvm内存中可以减少外部系统的压力,可以将频繁访问、且更新场景较少的数据缓存起来,降低对远程服务或者数据库的请求次数,降低外部系统负载,提供系统整体的稳定性缺点:但是同时也得......
  • Windows Packet Divert(WinDivert)是一个适用于Windows 10、Windows 11和Windows Server
    WindowsPacketDivert(WinDivert)是一个适用于Windows10、Windows11和WindowsServer的用户模式数据包捕获和重定向工具。WinDivert允许用户模式应用程序捕获/修改/丢弃发送到/从Windows网络堆栈的网络数据包。总之,WinDivert可以:捕获网络数据包过滤/丢弃网络数据包嗅探......
  • [AI][osg]关于osg的options的设计模式
    Options说明OSG(OpenSceneGraph)是一个高性能的开源3D图形工具包,用于可视化仿真、游戏、虚拟现实、科学可视化等领域。它提供了一套丰富的API和工具,帮助开发者创建复杂的3D场景和应用程序。在OSG中,Options机制用于控制场景图读取过程中的各种参数和行为。通过Options,开发者可以指......
  • 前端面试题:hash模式和history模式
    hash(哈希)和history(历史)是前端路由的两种模式,它们的主要区别在url,兼容性,服务器配置,美观性,和导航操作上面1,URLhash的url前面有#来表示路径,而history没有hash:hash模式是一种把前端路由的路径用#拼接在真实url后面的模式,通过hashchange事件监听hash值的改变来渲染页......
  • 代理模式(静态代理和动态代理)
    1.静态代理    静态代理中代理类与被代理类都需要实现同一个接口,这就说明我们的一个静态代理类只能代理一个类,并且还要事先知道我们要代理哪个类才能写代理类,如果我们有其他类还想使用代理那就必须再写一个代理类。【1】测试案例:法外狂徒张三叫律师打官司packageco......
  • Spring中用到的一些设计模式
    单例模式:bean默认就是单例原型模式:指定作用域为prototype工厂模式:BeanFactory模板方法:postProcessBeanFactory,onRefresh,initPropertyValue策略模式:xmlBeanDefinitionReader,PropertiesBeanDefinitionReader观察者模式:listener,event,multicast适配器模式:Adapter......
  • CentOS 7.9 快速搞定网络配置(NAT模式)
    本机网络配置:  2.虚拟机NAT模式配置  3.centos网卡配置vi/etc/sysconfig/network-scripts/ifcfg-ens33 TYPE=EthernetPROXY_METHOD=noneBROWSER_ONLY=noBOOTPROTO=staticDEFROUTE=yesIPV4_FAILURE_FATAL=noIPV6INIT=yesIPV6_AUTOCONF=yesIPV6_DEF......
  • B2C平台是什么?B2C模式为企业营销提供了哪些功能?
    B2C平台,全称为Business-to-Consumer平台,也就是企业对个人的电子商务模式,是指企业直接向消费者销售产品和服务的电子商务平台。这种模式消除了中间商的存在,使得企业能够直接与消费者进行交易,降低了成本,提高了效率。在当前的企业营销运营中,B2C平台承担着多种重要的功能。首先,它......