python之路,Day24 常用设计模式学习
本节内容
1.设计模式介绍设计模式(Design Patterns) ????????????????????????????????? ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。 2. 设计模式分类经典的《设计模式》一书归纳出23种设计模式,这23种模式又可归为,创建型、结构型和行为型3大类 2.1.创建型模式前面讲过,社会化的分工越来越细,自然在软件设计方面也是如此,因此对象的创建和对象的使用分开也就成为了必然趋势。因为对象的创建会消耗掉系统的很多资源,所以单独对对象的创建进行研究,从而能够高效地创建对象就是创建型模式要探讨的问题。这里有6个具体的创建型模式可供研究,它们分别是: 简单工厂模式(Simple Factory); 工厂方法模式(Factory Method); 抽象工厂模式(Abstract Factory); 创建者模式(Builder); 原型模式(Prototype); 单例模式(Singleton)。 说明:严格来说,简单工厂模式不是GoF总结出来的23种设计模式之一。 2.2?结构型模式在解决了对象的创建问题之后,对象的组成以及对象之间的依赖关系就成了开发人员关注的焦点,因为如何设计对象的结构、继承和依赖关系会影响到后续程序的维护性、代码的健壮性、耦合性等。对象结构的设计很容易体现出设计人员水平的高低,这里有7个具体的结构型模式可供研究,它们分别是: 外观模式(Facade); 适配器模式(Adapter); 代理模式(Proxy); 装饰模式(Decorator); 桥模式(Bridge); 组合模式(Composite); 享元模式(Flyweight) 2.3 行为型模式在对象的结构和对象的创建问题都解决了之后,就剩下对象的行为问题了,如果对象的行为设计的好,那么对象的行为就会更清晰,它们之间的协作效率就会提高,这里有11个具体的行为型模式可供研究,它们分别是: 模板方法模式(Template Method); 观察者模式(Observer); 状态模式(State); 策略模式(Strategy); 职责链模式(Chain of Responsibility); 命令模式(Command); 访问者模式(Visitor); 调停者模式(Mediator); 备忘录模式(Memento); 迭代器模式(Iterator); 解释器模式(Interpreter)。 3. 设计模式的六大原则1、开闭原则(Open Close Principle) 开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。 2、里氏代换原则(Liskov Substitution Principle) 里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。—— From Baidu 百科 3、依赖倒转原则(Dependence Inversion Principle) 这个是开闭原则的基础,具体内容:是对接口编程,依赖于抽象而不依赖于具体。 4、接口隔离原则(Interface Segregation Principle) 这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。 5、迪米特法则(最少知道原则)(Demeter Principle) 为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。 6、合成复用原则(Composite Reuse Principle) 原则是尽量使用合成/聚合的方式,而不是使用继承。 工厂模式工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
简单工厂模式
<span style="color: #0000ff;">class<span style="color: #000000;"> Circle(ShapeFactory):
<span style="color: #0000ff;">def <span style="color: #800080;">init<span style="color: #000000;">(self):self.shape_name = <span style="color: #800000;">"<span style="color: #800000;">Circle<span style="color: #800000;">" <span style="color: #0000ff;">def<span style="color: #000000;"> draw(self): <span style="color: #0000ff;">print(<span style="color: #800000;">'<span style="color: #800000;">draw circle<span style="color: #800000;">'<span style="color: #000000;">) <span style="color: #0000ff;">class<span style="color: #000000;"> Rectangle(ShapeFactory): <span style="color: #0000ff;">class<span style="color: #000000;"> Shape(object): fac =<span style="color: #000000;"> Shape() 优点:客户端不需要修改代码。缺点: 当需要增加新的运算类的时候,不仅需新加运算类,还要修改工厂类,违反了开闭原则。 工厂方法模式这个和简单工厂有区别,简单工厂模式只有一个工厂,工厂方法模式对每一个产品都有相应的工厂 好处:增加一个运算类(例如N次方类),只需要增加运算类和相对应的工厂,两个类,不需要修改工厂类。 缺点:增加运算类,会修改客户端代码,工厂方法只是把简单工厂的内部逻辑判断移到了客户端进行。
<span style="color: #0000ff;">class<span style="color: #000000;"> Circle(ShapeFactory):
<span style="color: #0000ff;">class<span style="color: #000000;"> Rectangle(ShapeFactory):<span style="color: #0000ff;">def <span style="color: #800080;">init<span style="color: #000000;">(self): self.shape_name = <span style="color: #800000;">"<span style="color: #800000;">Retangle<span style="color: #800000;">"
<span style="color: #0000ff;">class<span style="color: #000000;"> ShapeInterfaceFactory(object): <span style="color: #0000ff;">class<span style="color: #000000;"> ShapeCircle(ShapeInterfaceFactory): <span style="color: #0000ff;">class<span style="color: #000000;"> ShapeRectangle(ShapeInterfaceFactory): shape_interface =<span style="color: #000000;"> ShapeCircle() shape_interface2 =<span style="color: #000000;"> ShapeRectangle() 下面这个是用学校\课程来描述了一个工厂模式 '''
工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。 首先完全实现‘开-闭 原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。 工厂方法模式的对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不在负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。 工厂方法模式(Factory Method pattern)是最典型的模板方法模式(Templete Method pattern)应用。 ''' class AbstractSchool(object):
class AbstractCourse(object):
class LinuxOPSCourse(AbstractCourse):
class PythonCourse(AbstractCourse):
class BJSchool(AbstractSchool):
class SHSchool(AbstractSchool):
school1 = BJSchool() school1.info() school2.info()
抽象工厂模式每一个模式都是针对一定问题的解决方案。抽象工厂模式与工厂方法模式的最大区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则需要面对多个产品等级结构。 在学习抽象工厂具体实例之前,应该明白两个重要的概念:产品族和产品等级。 所谓产品族,是指位于不同产品等级结构中,功能相关联的产品组成的家族。比如AMD的主板、芯片组、CPU组成一个家族,Intel的主板、芯片组、CPU组成一个家族。而这两个家族都来自于三个产品等级:主板、芯片组、CPU。一个等级结构是由相同的结构的产品组成,示意图如下:
显然,每一个产品族中含有产品的数目,与产品等级结构的数目是相等的。产品的等级结构与产品族将产品按照不同方向划分,形成一个二维的坐标系。横轴表示产品的等级结构,纵轴表示产品族,上图共有两个产品族,分布于三个不同的产品等级结构中。只要指明一个产品所处的产品族以及它所属的等级结构,就可以唯一的确定这个产品。 上面所给出的三个不同的等级结构具有平行的结构。因此,如果采用工厂方法模式,就势必要使用三个独立的工厂等级结构来对付这三个产品等级结构。由于这三个产品等级结构的相似性,会导致三个平行的工厂等级结构。随着产品等级结构的数目的增加,工厂方法模式所给出的工厂等级结构的数目也会随之增加。如下图:
那么,是否可以使用同一个工厂等级结构来对付这些相同或者极为相似的产品等级结构呢?当然可以的,而且这就是抽象工厂模式的好处。同一个工厂等级结构负责三个不同产品等级结构中的产品对象的创建。 可以看出,一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象。显然,这时候抽象工厂模式比简单工厂模式、工厂方法模式更有效率。对应于每一个产品族都有一个具体工厂。而每一个具体工厂负责创建属于同一个产品族,但是分属于不同等级结构的产品。 抽象工厂模式结构抽象工厂模式是对象的创建模式,它是工厂方法模式的进一步推广。 假设一个子系统需要一些产品对象,而这些产品又属于一个以上的产品等级结构。那么为了将消费这些产品对象的责任和创建这些产品对象的责任分割开来,可以引进抽象工厂模式。这样的话,消费产品的一方不需要直接参与产品的创建工作,而只需要向一个公用的工厂接口请求所需要的产品。 通过使用抽象工厂模式,可以处理具有相同(或者相似)等级结构中的多个产品族中的产品对象的创建问题。如下图所示: 由于这两个产品族的等级结构相同,因此使用同一个工厂族也可以处理这两个产品族的创建问题,这就是抽象工厂模式。 根据产品角色的结构图,就不难给出工厂角色的结构设计图。 可以看出,每一个工厂角色都有两个工厂方法,分别负责创建分属不同产品等级结构的产品对象。 抽象工厂的功能是为一系列相关对象或相互依赖的对象创建一个接口。一定要注意,这个接口内的方法不是任意堆砌的,而是一系列相关或相互依赖的方法。比如上面例子中的主板和CPU,都是为了组装一台电脑的相关对象。不同的装机方案,代表一种具体的电脑系列。 由于抽象工厂定义的一系列对象通常是相关或相互依赖的,这些产品对象就构成了一个产品族,也就是抽象工厂定义了一个产品族。 这就带来非常大的灵活性,切换产品族的时候,只要提供不同的抽象工厂实现就可以了,也就是说现在是以一个产品族作为一个整体被切换。 在什么情况下应当使用抽象工厂模式1.一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。 2.这个系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。 3.同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。(比如:Intel主板必须使用Intel CPU、Intel芯片组) 4.系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。 抽象工厂模式的起源抽象工厂模式的起源或者最早的应用,是用于创建分属于不同操作系统的视窗构建。比如:命令按键(Button)与文字框(Text)都是视窗构建,在UNIX操作系统的视窗环境和Windows操作系统的视窗环境中,这两个构建有不同的本地实现,它们的细节有所不同。 在每一个操作系统中,都有一个视窗构建组成的构建家族。在这里就是Button和Text组成的产品族。而每一个视窗构件都构成自己的等级结构,由一个抽象角色给出抽象的功能描述,而由具体子类给出不同操作系统下的具体实现。 抽象工厂模式的优点
客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已。也就是说,客户端从具体的产品实现中解耦。
因为一个具体的工厂实现代表的是一个产品族,比如上面例子的从Intel系列到AMD系列只需要切换一下具体工厂。 抽象工厂模式的缺点
如果需要给整个产品族添加一个新的产品,那么就需要修改抽象工厂,这样就会导致修改所有的工厂实现类。 <div class="cnblogsHighlighter"> class AbstractFactory(object): class IntelFactory(AbstractFactory):
class AmdFactory(AbstractFactory):
class AbstractCpu(object): class IntelCpu(AbstractCpu): class IntelCpu(AbstractCpu): class AmdCpu(AbstractCpu): class AbstractMainboard(object): class IntelMainBoard(AbstractMainboard): class AmdMainBoard(AbstractMainboard): class ComputerEngineer(object):
-------- End --------
建造者模式
? <div class="cnblogsHighlighter"> 建造者模式相关模式:思路和模板方法模式很像,模板方法是封装算法流程,对某些细节,提供接口由子类修改,建造者模式更为高层一点,将所有细节都交由子类实现。建造者模式:将一个复杂对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示。基本思想某类产品的构建由很多复杂组件组成;这些组件中的某些细节不同,构建出的产品表象会略有不同;通过一个指挥者按照产品的创建步骤来一步步执行产品的创建;当需要创建不同的产品时,只需要派生一个具体的建造者,重写相应的组件构建方法即可。def printInfo(info): 建造者基类class PersonBuilder():
胖子class PersonFatBuilder(PersonBuilder):
瘦子class PersonThinBuilder(PersonBuilder):
指挥者class PersonDirector():
def clientUI():
if name == 'main':
?单例模式
?class MyClass(Singleton):
def init(self,name): self.name = name a = MyClass("Alex") print(a.name)
适配器模式?
<div class="cnblogsHighlighter"> 适配器模式将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。应用场景:希望复用一些现存的类,但是接口又与复用环境要求不一致。def printInfo(info): 球员类class Player():
前锋class Forwards(Player):
中锋(目标类)class Center(Player): def Attack(self): def Defense(self): 后卫class Guards(Player): def Attack(self): def Defense(self): 外籍中锋(待适配类)中锋class ForeignCenter(Player):
翻译(适配类)class Translator(Player):
def clientUI():
if name == 'main':
桥接模式参考:http://www.cnblogs.com/houleixx/archive/2008/02/23/1078877.html 生活中的一个例子: 就拿汽车在路上行驶的来说。即有小汽车又有公共汽车,它们都不但能在市区中的公路上行驶,也能在高速公路上行驶。这你会发现,对于交通工具(汽车)有不同的类型,然而它们所行驶的环境(路)也在变化,在软件系统中就要适应两个方面的变化?怎样实现才能应对这种变化呢?概述:在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,那么如何应对这种“多维度的变化”?如何利用面向对象的技术来使得该类型能够轻松的沿着多个方向进行变化,而又不引入额外的复杂度?这就要使用Bridge模式。意图: 将抽象部分与实现部分分离,使它们都可以独立的变化。 ——《设计模式》GOF效果及实现要点:1.Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。2.所谓抽象和实现沿着各自维度的变化,即“子类化”它们,得到各个子类之后,便可以任意它们,从而获得不同路上的不同汽车。3.Bridge模式有时候类似于多继承方案,但是多继承方案往往违背了类的单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。4.Bridge模式的应用一般在“两个非常强的变化维度”,有时候即使有两个变化的维度,但是某个方向的变化维度并不剧烈——换言之两个变化不会导致纵横交错的结果,并不一定要使用Bridge模式。适用性: 在以下的情况下应当使用桥梁模式:1.如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系。2.设计要求实现化角色的任何改变不应当影响客户端,或者说实现化角色的改变对客户端是完全透明的。3.一个构件有多于一个的抽象化角色和实现化角色,系统需要它们之间进行动态耦合。4.虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。总结: Bridge模式是一个非常有用的模式,也非常复杂,它很好的符合了开放-封闭原则和优先使用对象,而不是继承这两个面向对象原则 <div class="cnblogs_Highlighter"> class AbstractCar(object):
class Street(AbstractRoad):
class SpeedWay(AbstractRoad):
class Car(AbstractCar): class Bus(AbstractCar): if name == "main": 小汽车在高速上行驶
应用设计模式:?????? 桥接模式(Bridge)来做(多维度变化);?????? 结合上面的例子,增加一个维度"人",不同的人开着不同的汽车在不同的路上行驶(三个维度);???????结合上面增加一个类"人",并重新调用.代码实现: class AbstractCar(object):
'''车辆基类'''
class People(object): class Street(AbstractRoad):
class SpeedWay(AbstractRoad):
class Car(AbstractCar): class Bus(AbstractCar):
加上人class Man(People): 加上人class Woman(People): 小汽车在高速上行驶
组合模式
<div class="cnblogs_Highlighter"> 那么我们就根据我们会员卡的消费,来模拟一下组合模式的实现吧!let's go!首先:1.我们的部件有,总店,分店,加盟店!2.我们的部件共有的行为是:刷会员卡3.部件之间的层次关系,也就是店面的层次关系是,总店下有分店、分店下可以拥有加盟店。有了我们这几个必要条件后,我的要求就是目前店面搞活动当我在总店刷卡后,就可以累积相当于在所有下级店面刷卡的积分总额,设计的代码如下class Store(object):
class BranchStore(Store):
class JoinStore(Store):
if name == "main":
这样在累积所有子店面积分的时候,就不需要去关心子店面的个数了,也不用关系是否是叶子节点还是组合节点了,也就是说不管是总店刷卡,还是加盟店刷卡,都可以正确有效的计算出活动积分。什么情况下使用组合模式引用大话设计模式的片段:“当发现需求中是体现部分与整体层次结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑组合模式了。”
外观模式
<div class="cnblogsHighlighter"> 外观模式(Facade),为子系统中的一组接口提供一个一致的界面,定义一个高层接口,这个接口使得这一子系统更加容易使用。在以下情况下可以考虑使用外观模式:(1)设计初期阶段,应该有意识的将不同层分离,层与层之间建立外观模式。(2) 开发阶段,子系统越来越复杂,增加外观模式提供一个简单的调用接口。(3) 维护一个大型遗留系统的时候,可能这个系统已经非常难以维护和扩展,但又包含非常重要的功能,为其开发一个外观类,以便新系统与其交互。优点编辑(1)实现了子系统与客户端之间的松耦合关系。(2)客户端屏蔽了子系统组件,减少了客户端所需处理的对象数目,并使得子系统使用起来更加容易。def printInfo(info): class Stock():
class ETF():
class Future():
class NationDebt():
class Option():
基金class Fund():
def clientUI(): if name == 'main':
享元模式
享元模式(Flyweight):运用共享的技术有效地支持大量细粒度的对象。
抽象享元角色(Flyweight):此角色是所有的具体享元类的超类,为这些类规定出需要实现的公共接口或抽象类。那些需要外部状态(External State)的操作可以通过方法的参数传入。抽象享元的接口使得享元变得可能,但是并不强制子类实行共享,因此并非所有的享元对象都是可以共享的。具体享元(ConcreteFlyweight)角色:实现抽象享元角色所规定的接口。如果有内部状态的话,必须负责为内部状态提供存储空间。享元对象的内部状态必须与对象所处的周围环境无关,从而使得享元对象可以在系统内共享。有时候具体享元角色又叫做单纯具体享元角色,因为复合享元角色是由单纯具体享元角色通过复合而成的。复合享元(UnsharableFlyweight)角色:复合享元角色所代表的对象是不可以共享的,但是一个复合享元对象可以分解成为多个本身是单纯享元对象的组合。复合享元角色又称做不可共享的享元对象。这个角色一般很少使用。享元工厂(FlyweightFactoiy)角色:本角色负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。当一个客户端对象请求一个享元对象的时候,享元工厂角色需要检查系统中是否已经有一个符合要求的享元对象,如果已经有了,享元工厂角色就应当提供这个已有的享元对象;如果系统中没有一个适当的享元对象的话,享元工厂角色就应当创建一个新的合适的享元对象。客户端(Client)角色:本角色还需要自行存储所有享元对象的外部状态。内部状态与外部状态:在享元对象内部并且不会随着环境改变而改变的共享部分,可以称之为享元对象的内部状态,反之随着环境改变而改变的,不可共享的状态称之为外部状态。class FlyweightBase(object): 继承的子类必须初始化
class Spam(FlyweightBase):
class Egg(FlyweightBase):
spam1 = Spam(1,'abc') egg1 = Egg(1,'abc') egg2 = Egg(4,'abc')assert spam1 is spam2
代理模式
<div class="cnblogsHighlighter"> 代理模式应用特性:需要在通信双方中间需要一些特殊的中间操作时引用,多加一个中间控制层。结构特性:建立一个中间类,创建一个对象,接收一个对象,然后把两者联通起来class sender_base:
class send_class(sender_base):
class agent_class(sender_base):
class receive_class: if 'main' == name:
模板方法模式在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。
模板方法模式概述
在现实生活中,很多事情都包含几个实现步骤,例如请客吃饭,无论吃什么,一般都包含点单、吃东西、买单等几个步骤,通常情况下这几个步骤的次序是:点单 --> 吃东西 --> 买单。在这三个步骤中,点单和买单大同小异,最大的区别在于第二步——吃什么?吃面条和吃满汉全席可大不相同,如图1所示:图1 请客吃饭示意图在软件开发中,有时也会遇到类似的情况,某个方法的实现需要多个步骤(类似“请客”),其中有些步骤是固定的(类似“点单”和“买单”),而有些步骤并不固定,存在可变性(类似“吃东西”)。为了提高代码的复用性和系统的灵活性,可以使用一种称之为模板方法模式的设计模式来对这类情况进行设计,在模板方法模式中,将实现功能的每一个步骤所对应的方法称为基本方法(例如“点单”、“吃东西”和“买单”),而调用这些基本方法同时定义基本方法的执行次序的方法称为模板方法(例如“请客”)。在模板方法模式中,可以将相同的代码放在父类中,例如将模板方法“请客”以及基本方法“点单”和“买单”的实现放在父类中,而对于基本方法“吃东西”,在父类中只做一个声明,将其具体实现放在不同的子类中,在一个子类中提供“吃面条”的实现,而另一个子类提供“吃满汉全席”的实现。通过使用模板方法模式,一方面提高了代码的复用性,另一方面还可以利用面向对象的多态性,在运行时选择一种具体子类,实现完整的“请客”方法,提高系统的灵活性和可扩展性。模板方法模式定义如下:模板方法模式:定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。Template Method Pattern: Define the skeleton of an algorithm in an operation,deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.模板方法模式是一种基于继承的代码复用技术,它是一种类行为型模式。模板方法模式是结构最简单的行为型设计模式,在其结构中只存在父类与子类之间的继承关系。通过使用模板方法模式,可以将一些复杂流程的实现步骤封装在一系列基本方法中,在抽象父类中提供一个称之为模板方法的方法来定义这些基本方法的执行次序,而通过其子类来覆盖某些步骤,从而使得相同的算法框架可以有不同的执行结果。模板方法模式提供了一个模板方法来定义算法框架,而某些具体步骤的实现可以在其子类中完成。class Register(object):
class RegisterByQQ(Register):
class RegisterByWeiChat(Register):
if name == "main":
责任链模式
<div class="cnblogsHighlighter"> 职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。适用场景:1、有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定;2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求;3、处理一个请求的对象集合应被动态指定。class BaseHandler(object):
class RequestHandlerL1(BaseHandler): class RequestHandlerL2(BaseHandler): class RequestHandlerL3(BaseHandler): self._successor.handle(request)class RequestAPI(object):
if name == "main": 观察者模式
?<div class="cnblogsHighlighter"> 观察者(Observer)模式又名发布-订阅(Publish/Subscribe)模式当我们希望一个对象的状态发生变化,那么依赖与它的所有对象都能相应变化(获得通知),那么就可以用到Observer模式, 其中的这些依赖对象就是观察者的对象,那个要发生变化的对象就是所谓’观察者’class ObserverBase(object):
class Observer(ObserverBase):
class GCDViewer(object): class GMDViewer(object): if name == "main":
策略模式
class TravelStrategy(object):
''' 出行策略 '''
class AirplaneStrategy(TravelStrategy): class TrainStrategy(TravelStrategy): class CarStrategy(TravelStrategy): class BicycleStrategy(TravelStrategy): class TravelInterface(object):
坐飞机travel = TravelInterface(AirplaneStrategy()) travel.travel() 改开车travel.set_strategy(TrainStrategy())
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |