欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

设计模式-01综述

时间:2023-07-04
文章目录

1 六大原则

1.1 单一职责原则(Single Responsibility Principle)

1.1.1 问题场景1.1.2 解决方案1.1.3 单一职责的好处 1.2 里氏替换原则(Liskov Substitution Principle)

1.2.1 里氏替换原则弥补继承的缺陷1.2.2 里氏替换原则对继承进行了规则上的约束 1.3 依赖倒置原则(Dependence Inversion Principle)

1.3.1 依赖的三种写法1.3.2 最佳实践 1.4 接口隔离原则(Interface Segregation Principle)

1.4.1 “接口”概念1.4.2 与单一职责的区别1.4.3 最佳实践 1.5 迪米特法则(Law of Demeter)

1.5.1 优点与缺点1.5.2 最佳实践 1.6 开闭原则(Open Closed Principle)

1.6.1 开闭原则的核心1.6.2 最佳实践

1.6.2.1 抽象约束1.6.2.2 元数据(metadata)控制模块行为1.6.2.3 制定项目章程1.6.2.4 封装变化 1.7 六大设计原则应用 2 设计模式

2.1 设计模式的一般定义2.2 设计模式要素2.3 设计模式分类

2.3.1 根据目的分类2.3.2 根据范围分类 2.4 设计模式功能

设计模式是在软件开发中,经过验证的用于解决特定场景下,重复出现的特定问题的解决方案。

在了解设计模式之前,先了解下,任何设计模式都必须遵守的六大原则。

1 六大原则

万变不离其宗,不管是Java还是C++,凡是面向对象的编程语言,在设计上,尽管表现形式可能有所不同,但是其实质和所需遵守的原则都是一致的。这里介绍下设计模式中的六大原则,以便能更好的理解设计模式。

设计模式的六大原则有:

Single Responsibility Principle:单一职责原则Open Closed Principle:开闭原则Liskov Substitution Principle:里氏替换原则Law of Demeter:迪米特法则Interface Segregation Principle:接口隔离原则Dependence Inversion Principle:依赖倒置原则

把这六个原则的首字母联合起来(两个 L 算做一个)就是 SOLID (solid,稳定的),其代表的含义就是这六个原则结合使用的好处:建立稳定、灵活、健壮的设计。

1.1 单一职责原则(Single Responsibility Principle)

SRP的原话解释是:There should never be more than one reason for a class to change、-> 应该有且仅有一个原因引起类的变更。

1.1.1 问题场景

类C负责两个不同的职责:职责D1,职责D2。当由于职责D1需求发生改变而需要修改类C时,有可能会导致原本运行正常的职责D2功能发生故障。

单一职责最难划分的就是职责,一个职责一个接口,但问题是”职责“没有一个量化的标准,一个类到底要负责哪些职责?这些职责怎么细化?细化后是否都要有一个接口或类?这些都需要从实际的项目去考虑。

1.1.2 解决方案

遵循单一职责原则。分别建立两个类C1、C2,使C1完成职责D1功能,C2完成职责D2功能。这样,当修改类C1时,不会使职责D2发生故障风险;同理,当修改C2时,也不会使职责D1发生故障风险。

比如说一个用户类,应该把用户的信息抽取成一个BO(Business Object,业务对象),把行为抽取成一个Biz(Business Logic,业务逻辑)。这样前者的职责是收集和反馈用户的属性信息;后者的职责是完成用户信息的维护和变更。分成这样的两个接口来设计之后,这两个职责的变化就不会互相影响。

但是在有些情况下,过度的拆分职责为多个接口,会造成系统类的臃肿,过度设计的情况。如实现IP电话的功能功能,必须先支持网络协议处理,其次是数据交互。如果把这两个过度切分的话,在实现IP电话的功能时就必须使用组合,反而增加了复杂度。

在使用单一职责时,要根据实际情况进行分析和设计。

1.1.3 单一职责的好处

类的复杂性降低,实现什么职责都有清晰明确的定义;可读性提高,复杂性降低,那当然可读性提高了;可维护性提高,可读性提高,那当然更容易维护了;变更引起的风险降低,变更是必不可少的,如果接口的单一职责做得好,一个接口修改只对相应的实现类有影响,对其他的接口无影响,这对系统的扩展性、维护性都有非常大的帮助。 1.2 里氏替换原则(Liskov Substitution Principle)

LSP的英文解释为:Functions that use use pointers or references to base classes must be able to use objects of derived classes without knowing it、-> 所有引用基类的地方必须能透明地使用其子类的对象。

里氏替换原则的意思是,所有基类在的地方,都可以换成子类,程序还可以正常运行。这个原则是与面向对象语言的继承特性密切相关的。

1.2.1 里氏替换原则弥补继承的缺陷

在学习java类的继承时,我们知道继承有一些优点:

子类拥有父类的所有方法和属性,从而可以减少创建类的工作量。提高了代码的重用性。提高了代码的扩展性,子类不但拥有了父类的所有功能,还可以添加自己的功能。

但有优点也同样存在缺点:

继承是侵入性的。只要继承,就必须拥有父类的所有属性和方法。降低了代码的灵活性。因为继承时,父类会对子类有一种约束。增强了耦合性。当需要对父类的代码进行修改时,必须考虑到对子类产生的影响。

如何避免这些缺陷呢?方法是引入里氏替换原则。

1.2.2 里氏替换原则对继承进行了规则上的约束

里氏替换原则对继承进行了规则上的约束,这种约束主要体现在四个方面:

子类必须完全实现父类的方法

在类中调用其他类时务必要使用父类或接口,如果不能使用父类或接口,则说明类的设计已经违背了LSP原则。如果子类不能完整地实现父类的方法,或者父类的某些方法在子类中已经发生”畸变“,则建议断开父子继承关系,采用依赖、聚集、组合等关系代替继承。子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。父类中已实现的方法其实是一种已定好的规范和契约,如果我们随意的修改了它,那么可能会带来意想不到的错误。可以给父类的非抽象(已实现)方法加final修饰,这样就在语法层面控制了父类非抽象方法被子类重写而违反里氏替换原则。

子类中可以增加自己特有的方法

子类继承了父类,拥有了父类和方法,同时还可以定义自己有,而父类没有的方法。这是在继承父类方法的基础上进行功能的扩展,符合里氏替换原则。

当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松

LSP要求制定一个契约,就是父类或接口,这种设计方法也叫做Design by Contract。契约制定了,也就同时制定了前置条件(即方法的形参)和后置条件(即方法的返回值)。在实际应用中父类一般都是抽象类,子类是实现类,子类中方法的前置条件必须与超类中被覆写的方法的前置条件相同或者更宽松。

当子类的方法实现父类的(抽象)方法时,方法的后置条件(即方法的返回值)要比父类更严格

父类的一个方法的返回值是一个类型T,子类的相同方法(重载或覆写)的返回值为S,那么LSP就要求S必须小于或等于T。若在继承时,子类的方法返回值类型范围比父类的方法返回值类型范围大,在子类重写该方法时编译器会报错。 1.3 依赖倒置原则(Dependence Inversion Principle)

DIP的英文解释为

High level modules should not depend upon low level modules、Both should depend upon abstractions.Abstractions should not depend upon details、Details should depend upon abstractions.

中文解释为:

1、上层模块不应该依赖底层模块,它们都应该依赖于抽象。2、抽象不应该依赖于细节,细节应该依赖于抽象。

低层模块可以理解为实现业务逻辑的一个个原子逻辑(不能再次拆分的),而高层模块就是原子逻辑的再组装。对于jJava而言,抽象就是指接口或抽象类,两者都是不能直接被实例化的;细节就是实现类,实现接口或继承抽象类而产生的类就是细节,其特点就是可以直接被实例化,也就是可以加上一个关键字new产生一个对象。

依赖倒置原则在Java语言中的表现就是:

模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的;接口或抽象类不依赖于实现类;实现类依赖接口或抽象类。

就是“面向接口编程”——OOD(Object-Oriented Design,面向对象设计)

采用依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起的风险,提高代码的可读性和可维护性。

1.3.1 依赖的三种写法

依赖是可以传递的,对象的依赖关系有三种方式来传递:

构造函数传递依赖对象。在类中通过构造函数声明依赖对象,按照依赖注入的说法,这种方式叫作构造函数注入;Setter方法传递依赖对象。在抽象类中设置Setter方法声明依赖关系,依照依赖注入的说法,这是Setter依赖注入;接口声明依赖对象。在接口的方法中声明依赖对象,这种方法也叫做接口注入。 1.3.2 最佳实践

依赖倒置原则的本质就是通过抽象(接口或抽象类)使各个类或模块的实现彼此独立,不互相影响,实现模块间的松耦合。在实际项目中,如何应用这个规则呢,只要遵循以下几个规则就可以:

每个类尽量都有接口或抽象类,或者抽象类和接口两者都具备,这是依赖倒置的基本要求,有了抽象才可能依赖倒置;变量的表面类型尽量是接口或者是抽象类;任何类都不应该从具体类派生;尽量不要覆写基类的方法;结合里氏替换原则使用:接口负责定义public属性和方法,并且声明与其他对象的依赖关系,抽象类负责公共构造部分的实现,实现类准确的实现业务逻辑,同时在适当的时候对父类进行细化。 1.4 接口隔离原则(Interface Segregation Principle)

ISP的英文解释为:

Clients should not be forced to depend upon interfaces that they don`t use.The dependency of one class to another one should depend on the smallest possible.

中文解释为:

1、客户端不应该依赖它不需要的接口。2、类间的依赖关系应该建立在最小的接口上。

1.4.1 “接口”概念

这里的“接口”并非单纯的指Java中的Interface类型,而可以理解为:

实例接口(Object Interface),在Java中声明一个类,然后用new关键字产生一个实例,它是对一个类型的事物的描述,这是一种接口。类接口(Class Interface),Java中经常使用的interface关键字定义的接口。

所以通过此概念理解:类之间相关依赖的“接口”应该最小,最细化。

1.4.2 与单一职责的区别

接口隔离原则与单一职责的审视角度是不相同的,其区别如下:

单一职责要求的是类和接口职责单一,注重的是职责,这是业务逻辑上的划分。接口隔离原则要求接口的方法尽量少,提供给每个模块的都应该是单一接口,提供给几个模块就应该有几个接口,而不是建立一个庞大的臃肿的接口,容纳所有的客户端访问。

例如:一个登录接口有10个方法,这10个方法都放在一个接口中,并且提供给多个模块访问,各个模块按照规定的权限来访问,在系统外通过文档约束“不使用的方法不要访问”,按照单一职责原则是允许的,按照接口隔离原则是不允许的,因为它要求“尽量使用多个专门的接口”。

1.4.3 最佳实践

接口要尽量小,一个接口只服务于一个子模块或业务逻辑,根据接口隔离原则拆分接口时,首先必须满足单一职责原则;接口要高内聚,具体来讲就是在接口中尽量少公布public方法,接口是对外的承诺,承诺越少对系统的开发越有利,变更的风险也就越少,同时也有利于降低成本;已经被污染了的接口,尽量去修改,若变更的风险较大,则采用适配器模式进行转化处理;定制服务:定制服务是单独为一个个体提供优良的服务,要求是只提供访问者需要的方法;接口设计是有限度的:接口设计的粒度需要根据经验和常识进行合理的判断。 1.5 迪米特法则(Law of Demeter)

Law of Demeter,简称LoD,也称为最少知识原则,Least Knowledge Principle,简称LKP。其英文解释为:

Talk only to your immediate friends and not to strangers

中文解释为:

如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。

一个对象应该对其他对象有最少的了解,即一个类应该对自己需要耦合或调用的类知道得最少,只关注自己调用的public方法,其他的一概不关心。

1.5.1 优点与缺点

迪米特法则要求限制软件实体之间通信的宽度和深度,正确使用迪米特法则将有以下两个优点。

降低了类之间的耦合度,提高了模块的相对独立性。由于亲合度降低,从而提高了类的可复用率和系统的扩展性。

过度使用迪米特法则会使系统产生大量的中介类,从而增加系统的复杂性,使模块之间的通信效率降低。所以,在釆用迪米特法则时需要反复权衡,确保高内聚和低耦合的同时,保证系统的结构清晰。

1.5.2 最佳实践

迪米特法则的核心思想就是类间解耦,弱耦合,只有弱耦合了以后,类的复用率才可以提高。其要求的结果就是产生了大量的中转或跳转类,导致系统的复杂性提高,同时也为维护带来了的难度。因此在采用迪米特法则时,既要做到让结构清晰,又做到高内聚低耦合。

在实现时可以遵循以下几个思路:

只和有“关系”的类进行依赖,这里的“关系”指:组合、聚合、依赖等。即从依赖者的角度来说,只依赖应该依赖的对象。类之间的依赖也需要一定的限度。即从被依赖者的角度说,只暴露应该暴露的方法。一个类公开的public属性或方法越多,修改时涉及的面也就越大,变更引起的风险扩散也就越大。因此,为了保持依赖类间的距离,在设计时需要反复衡量:是否还可以再减少public方法和属性,是否可以修改为private、package-private(包类型,在类、方法、变量前不加访问权限,则默认为包类型)、protected等访问权限,是否可以加上final关键字等。如果一个方法放在本类中,既不增加类间关系,也对本类不产生负面影响,那就放置在本类中。 1.6 开闭原则(Open Closed Principle)

OCP的英文解释为:

Software entities like classes, modules and functions should be open for extension but closed for modification

中文解释为:

一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。

1.6.1 开闭原则的核心

开闭原则的定义已经非常明确地告诉我们:软件实体应该对扩展开放,对修改关闭,其含义是说一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化。那什么又是软件实体呢?软件实体包括以下几个部分:

项目或软件产品中按照一定的逻辑规则划分的模块。抽象和类。方法。

一个软件产品只要在生命期内,都会发生变化,既然变化是一个既定的事实,我们就应该在设计时尽量适应这些变化,以提高项目的稳定性和灵活性,真正实现“拥抱变化”。

开闭原则告诉我们应尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来完成变化,它是为软件实体的未来事件而制定的对现行开发设计进行约束的一个原则。

可以把变化归纳为以下三种类型:

逻辑变化
只变化一个逻辑,而不涉及其他模块,比如原有的一个算法是ab+c,现在需要修改为ab*c,可以通过修改原有类中的方法的方式来完成,前提条件是所有依赖或关联类都按照相同的逻辑处理。子模块变化
一个模块变化,会对其他的模块产生影响,特别是一个低层次的模块变化必然引起高层模块的变化,因此在通过扩展完成变化时,高层次的模块修改是必然的。可见视图变化
可见视图是提供给客户使用的界面,如JSP程序、Swing界面等,该部分的变化一般会引起连锁反应(特别是在国内做项目,做欧美的外包项目一般不会影响太大)。如果仅仅是界面上按钮、文字的重新排布倒是简单,最司空见惯的是业务耦合变化,什么意思呢?一个展示数据的列表,按照原有的需求是6列,突然有一天要增加1列,而且这一列要跨N张表,处理M个逻辑才能展现出来,这样的变化是比较恐怖的,但还是可以通过扩展来完成变化,这就要看我们原有的设计是否灵活。 1.6.2 最佳实践

开闭原则是一个非常虚的原则,前面5个原则是对开闭原则的具体解释,但是开闭原则并不局限于这么多,它“虚”得没有边界。那么在实际工作中可以通过如下几种方式来实现开闭原则:

1.6.2.1 抽象约束

抽象是对一组事物的通用描述,没有具体的实现,也就表示它可以有非常多的可能性,可以跟随需求的变化而变化。因此,通过接口或抽象类可以约束一组可能变化的行为,并且能够实现对扩展开放,其包含三层含义:

第一,通过接口或抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public方法;第二,参数类型、引用对象尽量使用接口或者抽象类,而不是实现类;第三,抽象层尽量保持稳定,一旦确定即不允许修改。 1.6.2.2 元数据(metadata)控制模块行为

编程是一个很苦很累的活,那怎么才能减轻我们的压力呢?答案是尽量使用元数据来控制程序的行为,减少重复开发。

什么是元数据?用来描述环境和数据的数据,通俗地说就是配置参数,参数可以从文件中获得,也可以从数据库中获得。

1.6.2.3 制定项目章程

在一个团队中,建立项目章程是非常重要的,因为章程中指定了所有人员都必须遵守的约定,对项目来说,约定优于配置。相信大家都做过项目,会发现一个项目会产生非常多的配置文件。

举个简单的例子,以SSH项目开发为例,一个项目中的Bean配置文件就非常多,管理非常麻烦。如果需要扩展,就需要增加子类,并修改SpringContext文件。然而,如果你在项目中指定这样一个章程:所有的Bean都自动注入,使用Annotation进行装配,进行扩展时,甚至只用写一个子类,然后由持久层生成对象,其他的都不需要修改,这就需要项目内约束,每个项目成员都必须遵守,该方法需要一个团队有较高的自觉性,需要一个较长时间的磨合,一旦项目成员都熟悉这样的规则,比通过接口或抽象类进行约束效率更高,而且扩展性一点也没有减少。

1.6.2.4 封装变化

对变化的封装包含两层含义:
第一,将相同的变化封装到一个接口或抽象类中;
第二,将不同的变化封装到不同的接口或抽象类中,不应该有两个不同的变化出现在同一个接口或抽象类中。

封装变化,也就是受保护的变化(protected variations),找出预计有变化或不稳定的点,我们为这些变化点创建稳定的接口,准确地讲是封装可能发生的变化,一旦预测到或“第六感”发觉有变化,就可以进行封装,23个设计模式都是从各个不同的角度对变化进行封装的,我们会在各个模式中逐步讲解。

1.7 六大设计原则应用

从整体上来理解六大设计原则,可以简要的概括为一句话,用抽象构建框架,用实现扩展细节,具体到每一条设计原则,则对应一条注意事项:

单一职责原则告诉我们实现类要职责单一;里氏替换原则告诉我们不要破坏继承体系;依赖倒置原则告诉我们要面向接口编程;接口隔离原则告诉我们在设计接口的时候要精简单一;迪米特法则告诉我们要降低耦合;开闭原则是总纲,告诉我们要对扩展开放,对修改关闭。 2 设计模式

1990年,软件工程界开始关注ChristopherAlexander等在这一住宅、公共建筑与城市规划领域的 重大突破。最早将模式的思想引入软件工程方法学的是1991-1992年以“四人组(Gang of Four, 简称GoF,分别是Erich Gamma, Richard Helm, Ralph Johnson和John Vlissides)”自称的四位著名 软件工程学者,他们在1994年归纳发表了23种在软件开发中使用频率较高的设计模式,旨在 用模式来统一沟通面向对象方法在分析、设计和实现间的鸿沟。

GoF将模式的概念引入软件工程领域,这标志着软件模式的诞生。软件模式(Software Patterns) 是将模式的一般概念应用于软件开发领域,即软件开发的总体指导思路或参照样板。软件模 式并非仅限于设计模式,还包括架构模式、分析模式和过程模式等,实际上,在软件开发生 命周期的每一个阶段都存在着一些被认同的模式。

软件模式是在软件开发中某些可重现问题的一些有效解决方法,软件模式的基础结构主要由 四部分构成,包括问题描述【待解决的问题是什么】、前提条件【在何种环境或约束条件下 使用】、解法【如何解决】和效果【有哪些优缺点】

2.1 设计模式的一般定义

设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过 分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人 理解并且保证代码可靠性。

狭义的设计模式是指GoF在《设计模式:可复用面向对象软件的基础》一书中所介绍的23种经 典设计模式,不过设计模式并不仅仅只有这23种,随着软件开发技术的发展,越来越多的新 模式不断诞生并得以应用。

2.2 设计模式要素

设计模式一般包含模式名称、问题、目的、解决方案、效果等组成要素,其中关键要素是模 式名称、问题、解决方案和效果。

2.3 设计模式分类

有一个设计模式虽然不属于GoF 23种设计模式,但一般在介绍设计模式时都 会对它进行说明,它就是简单工厂模式,也许是太“简单”了,GoF并没有把它写到那本经典著 作中,不过现在大部分的设计模式书籍都会对它进行专门的介绍。

2.3.1 根据目的分类

通过完成什么工作划分为创建型模式、结构型模式、行为型模式3种类型:

(1)创建型模式:抽象了对象实例化的过程,用来帮助床架对象的实例。
共五种: 工厂方法模式、抽象工厂模式、单例模式、构建者模式、原型模式。(2)结构型模式:描述如何组合类和对象以获得更大的结构。
共七种: 适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。(3)行为型模式:描述算法和对象间职责的分配。
共十一种: 策略模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、模板方法模式、备忘录模式、解释器模式。

其实还有两类:并发型模式和线程池模式。

2.3.2 根据范围分类

根据是用于类上还是用于对象上划分分为类模式和对象模式两种。

类模式:用于处理类与子类之间的关系,这些关系通过继承来建立,在编译时刻便确定下来了。工厂方法、(类)适配器、模板方法、解释器均属于该模式。对象模式:用于处理对象之间的关系,这些关系可以通过组合或聚合来实现,在运行时刻是可以变化的,更具动态性。除了以上 4 种,其他的都是对象模式。 范围/目的创建型模式结构型模式行为型模式类模式工厂方法模式(类)适配器模式解释器模式
模板方法模式对象模式简单工厂模式
抽象工厂模式
单例模式
建造者模式
原型模式(对象)适配器模式
桥接模式
组合模式
装饰模式
外观模式
享元模式
代理模式职责链模式
命令模式
迭代器模式
中介者模式
备忘录模式
观察者模式
状态模式
策略模式
访问者模式2.4 设计模式功能 单例(Singleton)模式:某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,其拓展是有限多例模式。原型(Prototype)模式:将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例。工厂方法(Factory Method)模式:定义一个用于创建产品的接口,由子类决定生产什么产品。
4.** 抽象工厂(AbstractFactory)模式**:提供一个创建产品族的接口,其每个子类可以生产一系列相关的产品。建造者(Builder)模式:将一个复杂对象分解成多个相对简单的部分,然后根据不同需要分别创建它们,最后构建成该复杂对象。代理(Proxy)模式:为某对象提供一种代理以控制对该对象的访问。即客户端通过代理间接地访问该对象,从而限制、增强或修改该对象的一些特性。适配器(Adapter)模式:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。桥接(Bridge)模式:将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。装饰(Decorator)模式:动态的给对象增加一些职责,即增加其额外的功能。外观(Facade)模式:为多个复杂的子系统提供一个一致的接口,使这些子系统更加容易被访问。享元(Flyweight)模式:运用共享技术来有效地支持大量细粒度对象的复用。组合(Composite)模式:将对象组合成树状层次结构,使用户对单个对象和组合对象具有一致的访问性。模板方法(TemplateMethod)模式:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。策略(Strategy)模式:定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的改变不会影响使用算法的客户。命令(Command)模式:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。职责链(Chain of Responsibility)模式:把请求从链中的一个对象传到下一个对象,直到请求被响应为止。通过这种方式去除对象之间的耦合。状态(State)模式:允许一个对象在其内部状态发生改变时改变其行为能力。观察者(Observer)模式:多个对象间存在一对多关系,当一个对象发生改变时,把这种改变通知给其他多个对象,从而影响其他对象的行为。中介者(Mediator)模式:定义一个中介对象来简化原有对象之间的交互关系,降低系统中对象间的耦合度,使原有对象之间不必相互了解。迭代器(Iterator)模式:提供一种方法来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。访问者(Visitor)模式:在不改变集合元素的前提下,为一个集合中的每个元素提供多种访问方式,即每个元素有多个访问者对象访问。备忘录(Memento)模式:在不破坏封装性的前提下,获取并保存一个对象的内部状态,以便以后恢复它。解释器(Interpreter)模式:提供如何定义语言的放法,以及对语言句子的解释方法,即解释器。

功能总结如下:

功能创建型模式结构型模式行为型模式对象创建单例
原型
工厂方法
抽象工厂
建造者接口适配适配器
桥接
外观对象去耦中介者
观察者抽象集合组合迭代器行为扩展装饰访问者
责任链算法封装模板方法
策略
命令性能与对象访问享元
代理对象状态备忘录
状态其他解释器

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。