当前位置: 首页 > news >正文

配色相关网站wordpress 支付宝插件下载

配色相关网站,wordpress 支付宝插件下载,2021年房价下跌已成定局,双峰网站建设目录 六大设计原则#xff08; SOLID #xff09;单一职责原则里氏替换原则迪米特法则接口隔离原则依赖倒置原则开闭原则 单例模式#xff08;创建型#xff09;概述实现使用装饰器使用基类使用元类 工厂模式#xff08;创建型#xff09;概述简单工厂工厂方法抽象工厂 建… 目录 六大设计原则 SOLID 单一职责原则里氏替换原则迪米特法则接口隔离原则依赖倒置原则开闭原则 单例模式创建型概述实现使用装饰器使用基类使用元类 工厂模式创建型概述简单工厂工厂方法抽象工厂 建造者模式创建型概述实现 策略模式行为型概述实现 观察者模式行为型概述实现 代理模式结构型概述实现实现缓存实现远程服务代理 装饰器模式结构型概述实现 适配器模式结构型概述实现 六大设计原则 SOLID 单一职责原则 单一职责原则Single Responsibility Principle一个类应该只有一个发生变化的原因。 主要为了不要让一个类承担过多的职责。避免职责耦合在一起避免一个职责的变化影响到其他职责。 举个例子一个视频播放系统一个客户端类有两个功能接口视频播放接口和音频播放接口。虽然这样的设计很常见但却不满足单一职责原则的。原因是如果对视频播放有变更需求或者对音频播放有修改需求都会变更视频客户端的类结构。符合单一原则的设计是将视频播放单元和音频播放单元各建一个类播放客户端继承两个类构成客户端。 单一职责原则的最大难点在于职责的划分试想以上划分是否是符合单一职责了既是也不是。试想如果将视频传输和音频传输的协议信息和数据信息区分开为符合这种粒度的单一职责原则就必须要有协议传输类和数据传输类的划分。如果接着细分可能一个简单的小模块都要设计非常多的类。因此单一职责原则粒度的选择应该根据业务流程和人员分工来进行考虑。一些基本的划分似乎已经成了行业规范性的内容比如业务逻辑与用户信息管理的划分等。 单一职责的好处 类的复杂性降低实现什么职责都有清晰明确的定义 可读性高复杂性降低可读性自然就提高了 可维护性提高可读性提高了那自然更容易维护了 变更引起的风险降低变更是必不可少的如果接口的单一职责做得好一个接口修改只对相应的实现类有影响对其他的接口无影响这对系统的扩展性、维护性都有非常大的帮助。 里氏替换原则 里氏替换原则Liskov Substitution Principle所有引用基类的地方必须能透明地使用其子类的对象。 通俗点讲就是只要父类能出现的地方子类就可以出现而且替换为子类也不会产生任何错误或异常。 可以理解为子类继承父类时尽量不要修改父类方法预期的行为也就是尽量不要重写父类方法。 在运用里氏代换原则时我们尽量把父类设计为抽象类或者接口让子类继承父类或实现父接口并实现在父类中声明的方法在运行时再确定其子类类型用子类实例来替换父类实例。 迪米特法则 迪米特法则Law of Demeter只与你的直接朋友交谈不跟“陌生人”说话。 通俗的讲一个类对自己需要耦合的类应该知道的最少你内部多么复杂和我没关系我只对你提供的public方法感兴趣。这样的话如果一个系统符合迪米特法则那么当其中某一个类发生修改时就会尽量少地影响其他模块降低系统的耦合度使类与类之间保持松散的耦合关系。 接口隔离原则 接口隔离原则Interface Segregation Principle建立单一接口而不是建立庞大臃肿的接口尽量细化接口接口中的方法尽量少。 也就是说我们要为各个类建立专用的接口而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。 比如说定义了一个接口MyInterface。 public interface MyInterface{public void method1(); public void method2(); public void method3(); }但是实现类A只想实现接口中的method1方法而实现类B只想实现接口中的method2、method3方法。此时只写一个接口让A、B都去实现该接口的话会导致AB中会实现不需要的方法这样设计接口会导致接口比较臃肿因此我们应该要把这个接口拆分开来写。 接口隔离原则跟之前的单一职责原则很相似但其实不同。单一职责原则注重的是职责针对的是程序中的实现和细节而接口隔离原则注重的是对接口依赖的隔离主要针对抽象。 依赖倒置原则 依赖倒置原则Dependence Inversion Principle上层模块不应该依赖底层模块它们都应该依赖于抽象。 即接口或抽象类不依赖于实现类而实现类依赖接口或抽象类。 就是说如果类与类直接依赖细节那么就会直接耦合那么当修改时就会同时修改依赖者代码这样限制了可扩展性。依赖倒置就是为了解决耦合。让程序依赖于抽象。 依赖倒置原则可以减少类间的耦合性提高系统的稳定性降低并行开发引起的风险提高代码的可读性和可维护性。 开闭原则 开闭原则Open Closed Principle一个软件实体如类、模块和函数应该对扩展开放对修改关闭。 在开发过程中需求的变化如果要通过修改原有的代码来完成那么就很可能将新的错误引入到旧的代码中。因此才有了开放封闭原则。就是说需求改变时我们应该尽量通过拓展的方式、即加入新代码来实现变化。 开闭原则是最基础的一个原则前面介绍的5个原则都是开闭原则的具体形态而开闭原则才是其精神领袖。 单例模式创建型 概述 单例模式Singleton Pattern属于创建型模式。为了确保一个类只有一个实例而且自行实例化并向整个系统提供这个实例。 单例模式应该是所有设计模式中结构最简单的一个。 通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问从而方便对实例个数的控制并节约系统资源。 优点 1、由于单例模式要求在全局内只有一个实例因而可以节省比较多的内存空间 2、全局只有一个接入点可以更好地进行数据同步控制避免多重占用3、单例可长驻内存减少系统开销。 缺点 1、单例模式的扩展是比较困难的 2、赋于了单例以太多的职责某种程度上违反单一职责原则 3、单例模式是并发协作软件模块中需要最先完成的因而其不利于测试 4、单例模式在某种情况下会导致“资源瓶颈”。 应用场景 1、生成全局惟一的序列号 2、访问全局复用的惟一资源如磁盘、总线等 3、单个对象占用的资源过多如数据库等 4、系统全局统一管理如Windows下的Task Manager 5、网站计数器。 实现 使用装饰器 def singleton(cls):instances {}def wrapper(*args, **kwargs):if cls not in instances:instances[cls] cls(*args, **kwargs)return instances[cls]return wrappersingleton class Foo(object):passif __name__ __main__:foo1 Foo()foo2 Foo()print(foo1 is foo2)使用基类 class Singleton(object):_instance Nonedef __new__(cls, *args, **kwargs):if not hasattr(cls, _instance):cls._instance super(Singleton, cls).__new__(cls, *args, **kwargs)return cls._instance# 继承Singleton class Foo(Singleton):passif __name__ __main__:foo1 Foo()foo2 Foo()print(foo1 is foo2)使用元类 class Singleton(type):# 元类必须继承typedef __call__(cls, *args, **kwargs):if not hasattr(cls, _instance):cls._instance super(Singleton, cls).__call__(*args, **kwargs)return cls._instanceclass Foo(metaclassSingleton):passif __name__ __main__:foo1 Foo()foo2 Foo()print(foo1 is foo2)工厂模式创建型 参考https://www.cnblogs.com/Zzbj/p/15778464.html 概述 工厂模式Factory Pattern属于创建型模式它提供了一种创建对象的最佳方式。 在工厂模式中我们在创建对象时不会对客户端暴露创建逻辑并且是通过使用一个共同的接口来指向新创建的对象。 **意图**定义一个创建对象的接口让其子类自己决定实例化哪一个工厂类工厂模式使其创建过程延迟到子类进行。 **主要解决**主要解决接口选择的问题。 **何时使用**我们明确地计划不同条件下创建不同实例时。 简单工厂 统一使用一个类作为对外接口根据参数的不同去选择实例化不同的类。 两个产品(两种类型的书) class TechnicalBooks(object):技术书籍def publish(self):return Python-Bookclass LiteraryBooks(object):文学书籍def publish(self):return Black Hole Book# 现在我们有两种类型的书分别是TechnicalBooks和LiteraryBooks的书 # 按照我们平常的方法来实例化的话此时创建对象时是会对客户端暴露真正创建的类 it_books TechnicalBooks() ly_books LiteraryBooks()# 这时我们就可以构造一个简单工厂把所有实例化的过程封装在里面把真正实例的类隐藏起来 class SimpleFactory(object):简单工厂staticmethoddef publish_book(name):if name technical:return TechnicalBooks()elif name literary:return LiteraryBooks()it_books2 SimpleFactory.publish_book(technical) ly_books2 SimpleFactory.publish_book(literary)简单工厂的好处在于把不同类的实例化统一到一个工厂即不对外暴露真正的创建类也提供了一个对外的统一接口。 但是简单工厂也有一个缺点那就是违背了solid的 “开闭原则”假如我们还需要增加一种书籍那就必须要对简单工厂SimpleFactory进行源码的修改。 简单工厂使用场景 已经确定有多少具体的类不会再增加的情况下使用。 例如某个系统已经明确就只会有MySQL、Redis、MongoDB三个数据库的情况下可以直接使用简单工厂模式。 工厂方法 上面的简单工厂我们已经知道了如果新增一些类型的时候会违背软件设计中的开闭原则但是我们希望在扩展新的类时不要修改原有的代码。这个时候我们可以在简单工厂的基础上把SimpleFactory抽象成不同的工厂每个工厂对应生成自己的产品这就是工厂方法。 两个产品(两种类型的书)import abc# 真正进行实例化的类 class TechnicalBooks(object):技术书籍def publish(self):return Python-Bookclass LiteraryBooks(object):文学书籍def publish(self):return Black Hole Book# 抽象工厂先定义抽象类然后每种类型的书籍都有自己对于的工厂 class AbstractFactory(metaclassabc.ABCMeta):抽象工厂abc.abstractmethoddef publish_book(self):passclass TechnicalFactory(AbstractFactory):技术书籍工厂def publish_book(self):return TechnicalBooks()class LiteraryFactory(AbstractFactory):文学书籍工厂def publish_book(self):return LiteraryBooks()it_books2 TechnicalFactory().publish_book() ly_books2 LiteraryFactory().publish_book()这样每个工厂就只负责生产自己的产品避免了在新增产品时需要修改工厂的代码遵循了开闭原则如果需要新增产品时只需要增加相应的工厂即可。 比如要新增一种小说类型的书籍只需新增一个NovelBooks类和NovelFactory类。 工厂方法的使用场景 当系统中拥有的子类很多并且以后可能还需要不断拓展增加不同的子类时。当设计系统时还不能明确具体有哪些类时。 在工厂方法中使用者不需要知道具体的产品类名只需要知道其对应的工厂即可。 抽象工厂 工厂方法解决了开闭原则的问题但是我们出版书籍之前肯定还会有其他的步骤比如印刷。 如果每一个步骤我们就要写一个对应的工厂类那我们就会需要创建很多很多类了。 因此为了解决这个问题我们就要需要抽象工厂类让一个工厂可以生产同一类的多个产品或多个动作(步骤)这就是抽象工厂。 两个产品(两种类型的书)import abc# 印刷书籍 class PrintingTechnicalBooks(object):印刷技术书籍def printing(self):return Print-Python-Bookclass PrintingLiteraryBooks(object):印刷文学书籍def printing(self):return Print Black Hole Book# 出版书籍 class TechnicalBooks(object):出版技术书籍def publish(self):return Python-Bookclass LiteraryBooks(object):出版文学书籍def publish(self):return Black Hole Book# 抽象工厂先定义抽象类然后每种类型的书籍都有自己对于的工厂 class AbstractFactory(metaclassabc.ABCMeta):抽象工厂abc.abstractmethoddef print_book(self):passabc.abstractmethoddef publish_book(self):passclass TechnicalFactory(AbstractFactory):技术书籍工厂def print_book(self):return PrintingTechnicalBooks()def publish_book(self):return TechnicalBooks()class LiteraryFactory(AbstractFactory):文学书籍工厂def print_book(self):return PrintingLiteraryBooks()def publish_book(self):return LiteraryBooks()# 实例化工厂对象 it TechnicalFactory() ly LiteraryFactory()# 印刷书籍 it_print it.print_book() ly_print ly.print_book() # 出版书籍 it_publish it.publish_book() ly_publish ly.publish_book()抽象工厂模式与工厂方法模式的区别抽象工厂中的一个工厂对象可以负责多个不同产品对象的创建 。 抽象工厂的使用场景 当多个产品(步骤)集合在一起组成产品族时。对于一个产品族如果只想显示接口而不是实现时。 建造者模式创建型 参考https://blog.csdn.net/songpeiying/article/details/131902497 概述 如果我们想建造一个由多个部分构成的对象而且它的构成需要一步接着一步完成只有当各个部分都创建好这个对象才算是完整的。这就是建造者模式(Builder Pattern)。 建造者模式是一种创建型设计模式它可以将复杂对象的构造与表现分离这样同一个构造过程可用于创建多个不同表现形式。该模式通过一步一步创建复杂对象将对象的构造过程与表示过程解耦。 例如快餐店使用的就是建造者模式。即使存在多种汉堡和不同包装但是准备一个汉堡及打包的流程是相同的。经典汉堡和奶酪汉堡之间的区别在于表现而不是建造过程。指挥者是出纳员将需要准备什么产品传达给工作人员建造者是工作人员的个体关注具体的顺序。 优点 将对象的构造过程与其表现形式解耦可以灵活地组合不同的构造过程来得到不同的表现形式。使得代码结构更加清晰易于维护和扩展。可以有效地控制对象的创建过程生成符合设计要求的对象。 缺点 建造者模式需要编写较多的代码且在构造对象时需要一定的时间和精力。如果需要创建的对象较少或者结构较简单则建造者模式可能会增加代码的复杂性。 应用场景 一个对象经过多个步骤来创建并且要求构建过程可以产生不同的表现。 例如在 Web 开发中我们可以使用建造者模式来构建复杂的 HTML 页面、邮件消息等。在游戏开发中我们可以使用建造者模式来生成游戏场景、角色等。在数据库开发中我们可以使用建造者模式来构建 SQL 查询语句等。 实现 通常来说建造者模式包括以下几个组成部分 产品类Product表示被构造的复杂对象。抽象建造者类Builder声明抽象方法来构建不同部分的复杂对象。具体建造者类Concrete Builder实现抽象建造者类中的方法来构建对象的各个部分并返回构建好的对象。指挥者类Director负责调用具体建造者类中的方法来构建复杂对象。 具体的工作流程如下 创建一个产品类该类表示待构建的复杂对象可以包含多个部分。创建一个抽象的建造者类该类声明了构建不同部分的抽象方法。创建具体的建造者类该类实现抽象建造者类中的方法构建对象的各个部分并返回构建好的对象。创建一个指挥者类该类负责调用具体建造者类中的方法来构建复杂对象。在应用程序中创建具体建造者类的实例并将其传递给指挥者类。指挥者类使用具体建造者类中的方法来构建复杂对象。最后应用程序可以使用构建好的复杂对象。 假设我们需要构建一个计算机计算机包含CPU、内存、硬盘、显卡等部件。我们可以使用Python建造者模式来构建这个复杂对象。具体实现步骤如下 首先创建一个产品类——计算机类它包含CPU、内存、硬盘、显卡等部件并提供各个部件的设置和获取方法。然后创建一个抽象建造者类——计算机建造者类它声明了构建不同部分的抽象方法接着创建具体的建造者类——台式机建造者类和笔记本建造者类它们实现了抽象建造者类中的方法构建对象的各个部分并返回构建好的对象由于计算机建造的过程比较复杂我们需要创建一个指挥者类——计算机装配员类它负责调用具体建造者类中的方法来构建复杂对象最后我们可以使用以上代码来创建不同的计算机 代码如下 # 创建产品类 class Computer():def __init__(self):self.cpu Noneself.memory Noneself.hark_disk Noneself.graphics_card Nonedef set_cpu(self, cpu):self.cpu cpudef set_memory(self, memory):self.memory memorydef set_hard_disk(self, hard_disk):self.hark_disk hard_diskdef set_graphics_card(self, graphics_card):self.graphics_card graphics_carddef get_specs(self):specs fCPU:{self.cpu}\nMemory:{self.memory}\nHard Disk:{self.hark_disk}\nGraphics Card:{self.graphics_card}return specs# 创建抽象的建造者类 class ComputerBuilder():def build_cpu(self): # 声明构建不同部分的抽象方法passdef build_memory(self):passdef build_hard_disk(self):passdef build_graphics_card(self):passdef get_computer(self):pass# 创建具体的建造者类 class DesktopBuilder(ComputerBuilder): # 继承抽象的建造者类def __init__(self):self.computer Computer() # 初始化产品类def build_cpu(self): # 实现抽象建造者方法self.computer.set_cpu(Intel Core 7) # 设置产品类方法值def build_memory(self):self.computer.set_memory(16GB DDR4)def build_hard_disk(self):self.computer.set_hard_disk(1TB HDD)def build_graphics_card(self):self.computer.set_graphics_card(NVIDIA GTX 1050)def get_computer(self):return self.computerclass LaptopBuilder(ComputerBuilder):def __init__(self):self.computer Computer()def build_cpu(self):self.computer.set_cpu(Intel Core i5)def build_memory(self):self.computer.set_memory(8GB DDR4)def build_hard_disk(self):self.computer.set_hard_disk(256GB SSD)def build_graphics_card(self):self.computer.set_graphics_card(Intergrated)def get_computer(self):return self.computer # 创建指挥者 class ComputerAssembler:def __init__(self,builder):self.builder builderdef assemble(self):self.builder.build_cpu() # 调用具体建造者类方法self.builder.build_memory()self.builder.build_hard_disk()self.builder.build_graphics_card()return self.builder.get_computer() # 创建台式计算机 desktop_builder DesktopBuilder() desktop_assembler ComputerAssembler(desktop_builder) desktop desktop_assembler.assemble() print(desktop.get_specs())# 创建笔记本计算机 laptop_builder LaptopBuilder() laptop_assembler ComputerAssembler(laptop_builder) laptop laptop_assembler.assemble() print(laptop.get_specs())策略模式行为型 参考https://blog.csdn.net/songpeiying/article/details/131939340 概述 策略模式Strategy是一种行为型策略模式。定义一系列的算法把它们一个个封装起来并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化从而达到代码的可扩展性、灵活性和可维护性。 优点 代码可扩展性和灵活性好能够适应不同的需求。降低模块之间的耦合度提高代码的可维护性和可读性。具有良好的可扩展性可以动态地增加、删除或替换算法。 缺点 会增加一定的复杂度需要额外的类定义。可能会导致系统中出现较多的类增加系统的复杂度需要客户端了解不同策略的差异才能选择合适的策略。 应用场景 1.需要在运行时根据不同情况选择不同算法的场景。 2.需要封装业务逻辑的场景。 3.需要对同一种算法进行多次修改的场景。 实现 策略模式实现通常需要以下三个角色 抽象出一个策略接口定义策略的方法。将不同的算法分别封装为具体的策略类并实现策略接口的方法。创建一个策略上下文类负责调用不同的策略根据不同的需求选择合适的策略。 以电商中的出校策略为例客户可以根据自己需要选择不同的促销策略比如有满减策略和折扣策略。 代码如下 # 定义促销策略接口 class PromotionStrategy():# 定义促销活动方法def do_promotion(self, price):pass# 定义具体促销策略 class ReductionPromotion(PromotionStrategy): # 满减def do_promotion(self, price):if price 200:return price - 50return priceclass DiscountPromotion(PromotionStrategy): # 折扣def do_promotion(self, price):return price * 0.8# 定义上下文类负责调用不同的促销策略 class PromotionContext():def __init__(self, promotion_strategy: PromotionStrategy):self._promotion_strategy promotion_strategydef execute_promotion_strategy(self, price):return self._promotion_strategy.do_promotion(price)# 使用满减策略计算价格 promotion_context PromotionContext(ReductionPromotion()) print(promotion_context.execute_promotion_strategy(200)) # 使用折扣策略计算价格 promotion_context PromotionContext(DiscountPromotion()) print(promotion_context.execute_promotion_strategy(200))观察者模式行为型 参考https://blog.csdn.net/songpeiying/article/details/131945036 概述 观察者模式Observer Pattern又叫做发布-订阅Publish/Subscribe模式、模型-视图Model/View模式。 观察者模式定义了对象间的一种一对多依赖关系使得每当一个对象状态发生改变时其相关依赖对象皆得到通知并被自动更新。 例如在MVC模式中有这样一个非常常见的例子假设在两个视图(例如一个饼图和一个电子表格)中使用同一个模型的数据无论何时更改了模型都需要更新两个视图。这就是观察者设计模式要处理的问题。 观察者模式描述单个对象发布者又称为主持者或可观察者与一个或多个对象订阅者又称为观察者之间的发布-订阅关系。在MVC例子中发布者是模型订阅者是视图。然而.MVC并非是仅有的发布-订阅例子。信息聚合订阅(比如RSS或Atom)是另一种例子。许多读者通常会使用一个信息聚合阅读器订阅信息流每当增加一条新信息时他们就能自动地获取到更新。 观察者模式背后的思想等同于MVC和关注点分离原则背后的思想即降低发布者与订阅者之间的耦合度从而易于在运行时添加/删除订阅者。此外发布者不关心它的订阅者是谁。它只是将通知发送给所有订阅者。 优点 提供灵活性减少类间的耦合度。可以实现动态的发布-订阅机制并且观察者可在运行时动态地加入或离开主题。实现开放-封闭原则使得主题和观察者可以独立地扩展和修改。 缺点 观察者过多会导致通知效率等性能问题。如果观察者与主题相互依赖修改其中任意一方的代码都需要修改对方的代码不利于系统的扩展和维护。 应用场景 当一个对象的改变需要同时改变其他对象时比如消息订阅模型。当一个抽象模型有两个方面其中一个方面需要依赖另外一个方面时。 实现 工作原理 观察者将自己注册到主题中。主题维护一个观察者列表。当主题状态发生改变时通知所有观察者。观察者执行相应的操作。 下面我们以一个简单的消息订阅系统为例详细说明 Python观察者模式实现消息订阅功能。 首先我们需要定义两个类主题类和观察者类。主题类包含一个观察者列表和通知观察者的方法观察者类包含需要执行的方法。NewsSubject类为新闻主题类包含observers字典和register_observer、remove_observer、notify_observers、set_news等方法。其中observers字典的键为订阅主题值为观察者列表。NewsObserver类为观察者类包含name属性和update方法。 接下来我们可以创建主题对象和观察者对象并将观察者对象注册到主题对象中。创建了一个主题对象subject和三个观察者对象observer_1、observer_2和observer_3并将观察者对象注册到主题对象中每个观察者订阅不同的新闻主题。 # *********************************观察者模式实现消息订阅功能# 新闻主题类 class NewsSubject():def __init__(self):self.observers {} # 字典self.news Nonedef register_observer(self, observer, topic):if topic not in self.observers:self.observers[topic] []self.observers[topic].append(observer)def remove_observer(self, observer, topic):if topic in self.observers:self.observers[topic].remove(observer)def notify_observers(self,topic):if topic in self.observers: # if语句存在观察者订阅的主题新闻通知观察者for observer in self.observers[topic]:observer.update(self.news) # 通知观察者新闻def set_news(self, news, topic):self.news newsself.notify_observers(topic)class NewsObserver():def __init__(self, name):self.name namedef update(self, news):print(f{self.name}收到新闻{news})subject NewsSubject()observer_1 NewsObserver(name1) observer_2 NewsObserver(name2) observer_3 NewsObserver(name3)subject.register_observer(observer_1, 国内新闻) subject.register_observer(observer_2, 国外新闻) subject.register_observer(observer_3, 娱乐新闻)subject.set_news(中国的新闻中国......, 国内新闻) subject.set_news(外国的新闻美国......, 国外新闻) subject.set_news(明星...,娱乐新闻) subject.set_news(歌星...,娱乐新闻)运行结果 name1收到新闻中国的新闻中国...... name2收到新闻外国的新闻美国...... name3收到新闻明星... name3收到新闻歌星...在上述代码中我们发布了三条新闻消息并使用set_news方法通知订阅相应主题的观察者。观察者会收到通知并执行相应的操作例如打印收到通知的信息。 这就是 Python观察者模式实现消息订阅功能的方法。当主题状态发生变化时通知所有订阅该主题的观察者执行相应的操作实现了消息订阅功能。 代理模式结构型 参考https://blog.csdn.net/songpeiying/article/details/131932669 概述 在某些应用中我们想要早访问某些对象之前执行一些重要操作。例如访问敏感信息之前做一些权限认证或者把一个创建成本较高的对象延迟到用户使用时才真正创建。 这类操作通常使用代理模式实现。 代理模式Proxy Pattern是一种结构型设计模式。在代理模式中代理对象充当了另一个对象的占位符以控制对该对象的访问。 代理对象和被代理对象实现了相同的接口因此它们可以互相替代。客户端和代理对象之间的交互是无缝的因为它们的接口是一样的。 代理模式的主要功能是为其他对象提供一个代理以控制对对象的访问。代理对象可以在调用被代理对象之前或之后执行一些操作例如身份验证缓存等。 优点 保护了真实对象的访问可以对访问进行限制和控制可以提高访问效率通过代理对象可以缓存数据或者调用其他服务等可以提高系统的灵活性因为代理对象可以在不影响真实对象的情况下扩展其功能。 缺点 可能引入额外的复杂性因为需要创建代理对象。此外如果代理对象没有正确实现与真实对象相同的接口可能会导致客户端代码无法正常工作。 应用场景 身份验证在访问某些敏感数据或操作时可以使用代理对象执行身份验证以确保用户有权访问该数据或执行该操作。缓存使用代理对象来缓存数据以便在下一次访问时可以更快地访问数据。远程服务代理对象可以用作远程服务的本地代表在使用远程服务时提供更好的用户体验同时也可以提高访问效率。 实现 代理模式可以通过组合或继承实现。通常代理对象会继承与真实对象相同的接口并在继承的方法中调用真实对象的方法。 实现缓存 假设我们正在开发一个网络应用程序该应用程序可以向外提供图片资源。由于图片资源较大我们希望通过代理模式来缓存这些数据以提高程序的性能和响应速度。 from abc import ABC, abstractmethod# 定义抽象基类 class Image():abstractmethoddef display(self):pass# 定义具体子类继承Image重新display方法 class RealImage(Image):def __init__(self, filename): # 构造函数接收一个参数filenameself.filename filename # 文件名保存在filename实例变量中self.load_from_disk() # 调用load_from_disk()方法从磁盘中加载图片数据从磁盘中加载图片数据子类RealImage独有的方法由于这个过程比较耗时因此我们需要在初始化时进行加载避免在图片显示时等待。def load_from_disk(self): #print(loading self.filename)# 显示图片def display(self):print(Displaying self.filename)# 定义代理类,继承Image,重写display方法 class ImageProxy(Image):def __init__(self, filename):self.filename filename# 定义真实图片self.real_image Nonedef display(self):if self.real_image is None:# 如果没有加载真实图片# 调用具体子类RealImage 创建真实图片对象 缓存真实对象避免重复加载图片资源self.real_image RealImage(self.filename)# 显示真实图片self.real_image.display()image ImageProxy(test.jpg) print(第一次调用display方法图片没有加载真实图片调用子类RealImage 创建真实图片对象) image.display() print(第二次调用display方法: 直接从缓存中获取图片) image.display()运行结果 第一次调用display方法图片没有加载真实图片调用子类RealImage 创建真实图片对象 loading test.jpg Displaying test.jpg 第二次调用display方法: 直接从缓存中获取图片 Displaying test.jpg在上面的示例中我们定义了一个抽象基类Image其中包含一个display()抽象方法。接着我们定义了一个具体子类RealImage它代表了真实的图片对象负责从磁盘中加载图片数据并提供display()方法用于显示图片。 我们还定义了一个代理类ImageProxy它也实现了Image接口。当客户端调用display()方法时代理类会检查是否已经加载了真实的图片对象。如果没有代理会先创建一个真实的图片对象然后再调用它的display()方法。这样代理对象就可以缓存真实对象避免了重复加载图片资源从而提高程序性能。 使用代理模式时客户端代码只需要与代理对象交互并不需要知道真实对象的存在。当代理对象需要访问真实对象时它会自动创建并调用真实对象从而实现对真实对象的间接访问。 实现远程服务代理 Python 代理模式实现远程服务功能 from abc import ABC, abstractmethod# 定义抽象类远程服务接口 class RemoteService():abstractmethoddef request(self, param: str) - str: # 抽象方法接受字符串类型参数返回字符串类型结果pass# 实现远程服务 class RemoteServiceIml(RemoteService):def request(self, param: str) - str:return fRemote service received {param}# 实现代理类 class RemoteServiceProxy(RemoteService):def __init__(self, remote_service: RemoteService):self._remote_service remote_servicedef request(self, param: str) - str:print(Remote service aouthentication...)# 调用远程服务器前本地操作...例如身份认证、参数校验if not param:raise ValueError(Missing parameter)# 调用远程服务返回结果return self._remote_service.request(param)remote_service_impl RemoteServiceIml() proxy RemoteServiceProxy(remote_service_impl)res proxy.request(test) print(res)运行结果 Remote service aouthentication... Remote service received test在上述代码中我们首先定义了一个远程服务接口RemoteService其中有一个request方法用于处理远程服务请求返回一个字符串类型的结果。同时我们还实现了RemoteServiceImpl类该类用于实现具体的远程服务逻辑。在具体的request方法中简单地将接收到的参数拼接成一条消息并返回。 接下来我们使用代理模式实现了RemoteServiceProxy类该类也实现了RemoteService接口并接收一个RemoteService实例作为构造函数参数。当我们调用request方法时代理类先进行身份认证、参数校验等本地操作然后再调用远程服务最后将结果返回。 装饰器模式结构型 概述 装饰器模式定义如下动态地给一个对象添加一些额外的职责。在增加功能方面装饰器模式比生成子类更为灵活。 装饰器模式和上一节说到的代理模式非常相似可以认为装饰器模式就是代理模式的一个特殊应用两者的共同点是都具有相同的接口不同点是侧重对主题类的过程的控制而装饰模式则侧重对类功能的加强或减弱。上一次说到JAVA中的动态代理模式是实现AOP的重要手段。而在Python中AOP通过装饰器模式实现更为简洁和方便。先来解释一下什么是AOP。AOP即Aspect Oriented Programming中文翻译为面向切面的编程它的含义可以解释为如果几个或更多个逻辑过程中这类逻辑过程可能位于不同的对象不同的接口当中有重复的操作行为就可以将这些行为提取出来即形成切面进行统一管理和维护。举例子说系统中需要在各个地方打印日志就可以将打印日志这一操作提取出来作为切面进行统一维护。从编程思想的关系来看可以认为AOP和OOP面向对象的编程是并列关系二者是可以替换的也可以结合起来用。 在Python语言中是天然支持装饰器的。 优点 增强已有函数的功能提高代码的复用性和可维护性不修改原函数的代码避免了可能引入的新问题。 缺点 由于装饰器本质上是一个函数因此会产生额外的函数调用开销如果装饰器过多会导致代码的可读性降低。 应用场景 缓存可以为一些需要大量计算的函数添加缓存功能减少函数的计算时间日志可以为一些需要记录日志的函数添加日志功能计时可以为一些需要计时的函数添加计时功能。 实现 可参考文章https://blog.csdn.net/qq_43745578/article/details/128710602 适配器模式结构型 概述 适配器模式 (Adapter pattem)是一种结构型设计模式帮助我们实现两个不兼容接口之间的兼容。首先解释一下不兼容接口的真正含义。如果我们希望把一个老组件用于一个新系统中或者把一个新组件用于一个老系统中不对代码进行任何修改两者就能够通信的情况很少见。但又并非总是能修改代码或因为我们无法访问这些代码( 例如组件以外部库的方式提供 )或因为修改代码本身就不切实际。在这些情况下我们可以编写一个额外的代码层该代码层包含让两个接口之间能够通信需要进行的所有修改。这个代码层就叫适配器。 例如一部智能手机或者一台平板电脑在想把它(比如iPhone手机的闪电接口)连接到你的电脑时就需要使用一个USB适配器。如果你从大多数欧洲国家到英国旅行,在为你的笔记本电脑充电时需要使用一个插头适配器。如果你从欧洲到美国旅行同样如此反之亦然。适配器无处不在! 适配器模式和装饰模式有一定的相似性都起包装的作用但二者本质上又是不同的装饰模式的结果是给一个对象增加了一些额外的职责而适配器模式则是将另一个对象进行了“伪装”。 优点 提高了系统的灵活性使得系统具备更好的可扩展性和可移植性。增强了系统的兼容性使得原本不兼容的类可以合作无间降低了系统维护成本。降低了系统耦合度减少了系统间的依赖关系。 缺点 适配器模式增加了代码的复杂度可能会影响系统性能。在适配器模式中适配器本身会成为系统的一个单点故障。 应用场景 系统需要与现有的代码或第三方库进行交互但它们的接口与系统的要求不符。 系统需要将同一接口的多个实现进行统一提高系统的可维护性和可扩展性。 工作原理 适配器模式主要由适配器、待适配接口和目标接口三个部分组成。 适配器通过继承或组合待适配接口实现目标接口使得待适配接口可以转换为目标接口。待适配接口需要被转换的原始接口。目标接口系统期望的兼容接口适配器将待适配接口转换为目标接口以满足系统间接口的兼容性需求。 实现 假设您有一个现有的类 Logger它提供了一种将消息记录到文件的方法。 此类需要将文件指定为文件路径字符串 class Logger:def __init__(self, file_path: str):self.file_path file_pathdef log(self, message: str):with open(self.file_path, a) as file:file.write(message \n)现在假设您有一个客户端想要使用 Logger 类但它希望传递一个文件对象而不是文件路径字符串。 在这种情况下您可以创建一个适配器类它接受一个文件对象并使用它来创建一个 Logger 实例 class FileLoggerAdapter:def __init__(self, file: File):self.logger Logger(file.name)def log(self, message: str):self.logger.log(message)此适配器类允许客户端代码使用 FileLoggerAdapter 类就好像它具有与 Logger 类相同的接口一样但它在幕后将文件对象转换为文件路径字符串。 客户端可以像这样使用适配器类 # Open a file for writing file open(log.txt, w)# Create a FileLoggerAdapter instance logger FileLoggerAdapter(file)# Log a message using the adapter logger.log(This is a log message)这个例子展示了如何使用适配器模式来允许两个具有不兼容接口的类无缝地协同工作。
http://www.zqtcl.cn/news/965278/

相关文章:

  • 2017优惠券网站怎么做坪山网站建设特色
  • wordpress 多站点模式望江网站建设
  • 常熟网站制作哪家好平面素材设计网站
  • 网站建设客户怎么找网站建设开发软件
  • 青岛制作企业网站的公司怎么清空WordPress
  • 权重的网站所有网站302跳转百度
  • 做个淘宝客网站怎么做济南网络推广公司排名
  • 西宁网站建设优化东莞建网站公司案例
  • 建设网站iss手工活接单在家做有正规网站吗
  • 六安做网站的公司专门建立网站的公司吗
  • 西昌市建设工程管理局网站wordpress主题知更
  • 企业网站如何上存青岛做外贸网站哪家好
  • 保定网站建设冀icp备织梦设置中英文网站
  • 烟台市建设工程检测站网站妖姬直播
  • 式网站西安网页搭建
  • 百度云虚拟主机如何建设网站四川建设人员信息查询
  • 浅谈学校网站建设html5网页制作代码成品
  • 网站在当地做宣传郑州高端设计公司
  • 一级a做爰网站微网站建设平台
  • 网站建设 中广州网站建设+致茂
  • 常德车管所网站工作微信管理系统
  • 什么软件可以做dj视频网站做的好的装修公司网站
  • 网站维护的内容和步骤如何建设像艺龙一样网站
  • 外国人做的学汉字网站公司网页需要哪些内容
  • 网站做缓存企业营销型网站的内容
  • 免费带后台的网站模板wordpress vr主题公园
  • 美丽乡村 网站建设wordpress分页工具栏
  • 卡盟网站是怎么建设的产品开发设计
  • 第一免费营销型网站一起做网店17
  • 高端学校网站建设做网站是怎么赚钱的