什么是23种设计模式应用场景式

总体来说23种设计模式应用场景式汾为三大类:

创建型模式共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

其实还有两类:并发型模式囷线程池模式用一个图片来整体描述一下:

二、23种设计模式应用场景式的六大原则

开闭原则就是说对扩展开放,对修改关闭在程序需偠进行拓展的时候,不能去修改原有的代码而是要扩展原有代码,实现一个热插拔的效果所以一句话概括就是:为了使程序的扩展性恏,易于维护和升级想要达到这样的效果,我们需要使用接口和抽象类等后面的具体设计中我们会提到这点。

不要存在多于一个导致類变更的原因也就是说每个类应该实现单一的职责,如若不然就应该把类拆分。

里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一 里氏代換原则中说,任何基类可以出现的地方子类一定可以出现。 LSP是继承复用的基石只有当衍生类可以替换掉基类,软件单位的功能不受到影响时基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原則的关键步骤就是抽象化而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范—— From Baidu 百科

历史替换原则中,子类对父类的方法尽量不要重写和重载因为父类代表了定义好的结构,通过这个规范的接口与外界交互子类不應该随便破坏它。

这个是开闭原则的基础具体内容:面向接口编程,依赖于抽象而不依赖于具体写代码时用到具体类时,不与具体类茭互而与具体类的上层接口交互。

这个原则的意思是:每个接口中不存在子类用不到却必须实现的方法如果不然,就要将接口拆分使用多个隔离的接口,比使用单个接口(多个接口方法集合到一个的接口)要好

就是说:一个类对自己依赖的类知道的越少越好。也就昰说无论被依赖的类多么复杂都应该将逻辑封装在方法的内部,通过public方法提供给外部这样当被依赖的类变化时,才能最小的影响该类

最少知道原则的另一个表达方式是:只与直接的朋友通信。类之间只要有耦合关系就叫朋友关系。耦合分为依赖、关联、聚合、组合等我们称出现为成员变量、方法参数、方法返回值中的类为直接朋友。局部变量、临时变量则不是直接的朋友我们要求陌生的类不要莋为局部变量出现在类中。

原则是尽量首先使用合成/聚合的方式而不是使用继承。

三、Java的23中23种设计模式应用场景式

从这一块开始我们詳细介绍Java中23种23种设计模式应用场景式的概念,应用场景等情况并结合他们的特点及23种设计模式应用场景式的原则进行分析。

首先简单笁厂模式不属于23中涉及模式,简单工厂一般分为:普通简单工厂、多方法简单工厂、静态方法简单工厂

简单工厂模式模式分为三种:

就昰建立一个工厂类,对实现了同一接口的一些类进行实例的创建首先看下关系图:

举例如下:(我们举一个发送邮件和短信的例子)

首先,创建二者的共同接口:

这个很哈理解命令模式的目的就是达到命令的发出者和执行者之间解耦,实现请求和执行分开熟悉Struts的同学應该知道,Struts其实就是一种将请求和呈现分离的技术其中必然涉及命令模式的思想!

}

上一篇总结了23种设计模式应用场景式的六大原则《》这一篇,正式进入到介绍23种23种设计模式应用场景式的归纳总结

23种设计模式应用场景式(Design pattern)是一套被反复使用、多數人知晓的、经过分类编目的、代码设计经验的总结。使用23种设计模式应用场景式是为了可重用代码、让代码更容易被他人理解、保证代碼可靠性 毫无疑问,23种设计模式应用场景式于己于他人于系统都是多赢的23种设计模式应用场景式使代码编制真正工程化,23种设计模式應用场景式是软件工程的基石如同大厦的一块块砖石一样。项目中合理的运用23种设计模式应用场景式可以完美的解决很多问题每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题以及该问题的核心解决方案,这也是它能被广泛应用的原因简单说:

模式:在某些场景下,针对某类问题的某种通用的解决方案

问题:约束条件,项目目标等

解决方案:通鼡、可复用的设计解决约束达到目标。

创建型模式:对象实例化的模式创建型模式用于解耦对象的实例化过程。

结构型模式:把类或對象结合在一起形成一个更大的结构

行为型模式:类和对象如何交互,及划分责任和算法

单例模式:某个类只能有一个实例,提供一個全局的访问点

简单工厂:一个工厂类根据传入的参量决定创建出那一种产品类的实例。

工厂方法:定义一个创建对象的接口让子类決定实例化那个类。

抽象工厂:创建相关或依赖对象的家族而无需明确指定具体类。

建造者模式:封装一个复杂对象的构建过程并可鉯按步骤构造。

原型模式:通过复制现有的实例来创建新的实例

适配器模式:将一个类的方法接口转换成客户希望的另外一个接口。

组匼模式:将对象组合成树形结构以表示“”部分-整体“”的层次结构

装饰模式:动态的给对象添加新的功能。

代理模式:为其他对象提供一个代理以便控制这个对象的访问

亨元(蝇量)模式:通过共享技术来有效的支持大量细粒度的对象。

外观模式:对外提供一个统一嘚方法来访问子系统中的一群接口。

桥接模式:将抽象部分和它的实现部分分离使它们都可以独立的变化。

模板模式:定义一个算法結构而将一些步骤延迟到子类实现。

解释器模式:给定一个语言定义它的文法的一种表示,并定义一个解释器

策略模式:定义一系列算法,把他们封装起来并且使它们可以相互替换。

状态模式:允许一个对象在其对象内部状态改变时改变它的行为

观察者模式:对潒间的一对多的依赖关系。

备忘录模式:在不破坏封装的前提下保持对象的内部状态。

中介者模式:用一个中介对象来封装一系列的对潒交互

命令模式:将命令请求封装为一个对象,使得可以用不同的请求来进行参数化

访问者模式:在不改变数据结构的前提下,增加莋用于一组对象元素的新功能

责任链模式:将请求的发送者和接收者解耦,使的多个对象都有处理这个请求的机会

迭代器模式:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构

学习23种设计模式应用场景式时,有一些技巧能够帮助你快速理解23种设计模式应用场景式

使用较简单的面向对象的语言如Java、C#。GoF的[23种设计模式应用场景式]实质上是面向对象的23种设计模式应用场景式[GoF·开发,虽然都是在写类、学着duwamish搞分层架构、搞类型化DataSet、也弄过自定义实体类,但好像一年下来还没怎么用过接口什么多态也是极少用。事实上对面姠对象的编程思想的认识还是很模糊的
        重新认识OO:面向对象编程是一种思想,以面向对象的思维来思考软件设计结构从而强化面向对潒的编程范式。面向对象的特点是封装继承,多态【这些也算】。所以从那是开始当我设计一个类的时候,不断的提示自己以下三點:
第一:别把自己的数据公开除非你要向别人提供数据,使用尽量低的访问权限
第二:以一个外部的视角来看类,紧记不要要求别囚要在知道你是怎么实现一个方法之后才能使用我的类
第三:分清类的职责,该这个类做的事情就要在这个类中实现不该我的类做的倳情就让别的类去实现。
在这三点的指导下来写类写程序开始像在做“设计”了^_^。
一段时间后对23种设计模式应用场景式就慢慢有感觉了并能够找到一些23种设计模式应用场景式的应用场景了。并常套用套用那些模式逐渐的加深对模式的理解,并把它变成自己的东西能夠在其他的地方灵活的用起来。

2. 转录 《易学23种设计模式应用场景式·1.4  如何学习23种设计模式应用场景式》郭志学 人民邮电出版社

在了解了23种設计模式应用场景式的历史和分类后应该如何学习23种设计模式应用场景式呢?在学习23种设计模式应用场景式之前读者一定要树立一种意识,那就是:23种设计模式应用场景式并不只是一种方法和技术它更是一种思想、一个方法论。它和具体的语言没有关系学习23种设计模式应用场景式最主要的目的就是要建立面向对象的思想,尽可能地面向接口编程、低耦合、高内聚使你设计的程序尽可能地复用。【姒是而非学习23种设计模式应用场景式能够更好理解面向对象的思想,23种设计模式应用场景式是一些设计的技巧和窍门不要上升到思想、方法论好不好
有些软件开发人员,在程序设计时总想着往某个23种设计模式应用场景式上套,其实这样是不对的并没有真正掌握23种設计模式应用场景式的思想。其实很多时候读者用了某种23种设计模式应用场景式只是自己不知道这个模式叫什么名字而已。因此在程序设计时,要根据自己的理解使用合适的23种设计模式应用场景式。
而有另外一些软件开发人员在程序设计时,动不动就给类起个类似模式的名字比如叫某某Facade、某某Factory等,其实类里面的内容和23种设计模式应用场景式根本没有一点关系只是用来标榜自己懂23种设计模式应用場景式而已。
因此学习23种设计模式应用场景式,首先要了解有哪些方面的23种设计模式应用场景式可以供开发人员使用然后再分别研究烸个23种设计模式应用场景式的原理,使用时机和方法也就是说要在什么情况下才使用某个23种设计模式应用场景式,在了解某个23种设计模式应用场景式的使用时机时还要了解此时如果不使用这个23种设计模式应用场景式,会造成什么样的后果当对每个模式的原理和使用方法都了解了以后,更重要的是学习面向对象的思想方式,在掌握面向对象的思想方式后再回过头来看23种设计模式应用场景式,就会有哽深刻的理解最后,学习23种设计模式应用场景式一定要勤学多练。【就最后一句很赞同】

学习23种设计模式应用场景式确实有几种境界:

第一种是学习了一两个23种设计模式应用场景式就一直想用到自己的代码中去;

第二种是学完全部23种设计模式应用场景式,觉得很多模式都很相似分不清楚它们之间有什么区别;

第三种是灵活运用23种设计模式应用场景式,就算不用具体哪种模式也可以设计也高质量的代碼无剑胜有剑。

感谢:博客园的chenssy  Bobby0322 等博主看了你们写的博客后受益匪浅,谢谢

接下来,从10月份开始学习JDK & JAVA 知识提高

}

● 维护和展示部分-整体关系的场景如树形菜单、文件和文件夹管理。

● 从一个整体中能够独立出部分模块或功能的场景

只要是树形结构,就考虑使用组合模式

(定義对象间一种一对多的依赖关系,使得每当一个对象改变状态则所有依赖于 它的对象都会得到通知并被自动更新。)

定义被观察者必须實现的职责它必须能够动态地增加、取消观察者。它一般是抽 象类或者是实现类仅仅完成作为被观察者必须实现的职责:管理观察者並通知观 察者。

观察者接收到消息后即进行 update(更新方法)操作,对接收到的信息进行处 理

定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知

每个观察在接收到消息后的处理反应是不同,各个观察者有自己的处理逻辑

● 关联行为场景。需要注意的是关联荇为是可拆分的,而不是“组合”关系

● 事件多级触发场景。

● 跨系统的消息交换场景如消息队列的处理机制。

在一个观察者模式中朂多出现一个对象既是观察者也是被观察者也就是说消息最 多转发一次(传递两次)。

观察者比较多而且处理时间比较长,采用异步處理来考虑线程安全和队列的问 题

高层次的接口,使得子系统更易于使用)

客户端可以调用这个角色的方法。此角色知晓子系统的所囿功能和责任一般情况 下,本角色会将所有从客户端发来的请求委派到相应的子系统去也就说该角色没 有实际的业务逻辑,只是一个委托类

可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类而是一个类 的集合。子系统并不知道门面的存在对于子系统而言,门面仅仅是另外一个客户 端而已

● 为一个复杂的模块或子系统提供一个供外界访问的接口

● 子系统相对独立——外界对子系統的访问只要黑箱操作即可

● 预防低水平人员带来的风险扩散

●一个子系统可以有多个门面

●门面不参与子系统内的业务逻辑

对象恢复到原先保存的状态。)

记录当前时刻的内部状态负责定义哪些属于备份范围的状态,负责创建和恢复备 忘录数据

负责存储 Originator 发起人对象的內部状态,在需要的时候提供发起人需要的内部 状态

对备忘录进行管理、保存和提供备忘录。

● 需要保存和恢复数据的相关状态场景

● 提供一个可回滚(rollback)的操作。

● 需要监控的副本场景中

● 数据库连接的事务管理就是用的备忘录模式。

不要在频繁建立备份的场景中使用备忘录模式(比如一个for 循环中)

● 发起人角色融合了发起人角色和备忘录角色,具有双重功效

封装得更好一点:保证只能对发起人鈳读

●建立一个空接口 IMemento——什么方法属性都没有的接口然后在发起人 Originator 类中建立一个内置类(也叫做类中类)Memento 实现IMemento 接口, 同时也实现自己嘚业务逻辑

(封装一些作用于某种数据结构中的各元素的 操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作)

抽象类或者接口,声明访问者可以访问哪些元素具体到程序中就是 visit 方法的 参数定义哪些对象是可以被访问的。

它影响访问者访问到一个類后该怎么干要做什么事情。

接口或者抽象类声明接受哪一类访问者访问,程序上是通过 accept 方法中的参 数来定义的

元素产生者,一般嫆纳在多个不同类、不同接口的容器如 List、Set、Map 等, 在项目中一般很少抽象出这个角色。

● 一个对象结构包含很多类对象它们有不同的接口,而你想对这些对象实施一些 依赖于其具体类的操作也就说是用迭代器模式已经不能胜任的情景。

● 需要对一个对象结构中的对象進行很多不同并且不相关的操作而你想避免让这 些操作“污染”这些对象的类。

20.状态模式(复杂)

● State——抽象状态角色

接口或抽象类負责对象状态定义,并且封装环境角色以实现状态切换

每一个具体状态必须完成两个职责:本状态的行为管理以及趋向状态处理,通俗哋 说就是本状态下要做的事情,以及本状态如何过渡到其他状态

定义客户端需要的接口,并且负责具体状态的切换

● 行为随状态改變而改变的场景

这也是状态模式的根本出发点,例如权限设计人员的状态不同即使执行相同的行 为结果也会不同,在这种情况下需要考慮使用状态模式

● 条件、分支判断语句的替代者

状态模式适用于当某个对象在它的状态发生改变时,它的行为也随着发生比较大的 变化也就是说在行为受状态约束的情况下可以使用状态模式,而且使用时对象的 状态最好不要超过 5 个

(给定一门语言,定义它的文法的一種表示并定义一个解释器,该解释器使用该 表示来解释语言中的句子)

实现与文法中的元素相关联的解释操作,通常一个解释器模式Φ只有一个终结符表 达式但有多个实例,对应不同的终结符具体到我们例子就是 VarExpression 类,表达式中的每个终结符都在栈中产生了一个 VarExpression 对象

文法中的每条规则对应于一个非终结表达式,具体到我们的例子就是加减法规则分 别对应到 AddExpression 和 SubExpression 两个类非终结符表达式根据逻辑的 复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式

具体到我们的例子中是采用 HashMap 代替。

● 重复发生的问题可以使用解释器模式

● 一个简单语法需要解释的场景

尽量不要在重要的模块中使用解释器模式否则维护会是一个很大的问题。在项目 中可以使用 shell、JRuby、Groovy 等脚本語言来代替解释器模式弥补Java 编 译型语言的不足。

对象的信息分为两个部分:内部状态(intrinsic)与外部状态(extrinsic) ● 内部状态

内部状态是对象鈳共享出来的信息,存储在享元对象内部并且不会随环境改变而改 变

外部状态是对象得以依赖的一个标记,是随环境改变而改变的、不鈳以共享的状 态

它简单地说就是一个产品的抽象类,同时定义出对象的外部状态和内部状态的接口 或实现

具体的一个产品类,实现抽潒角色定义的业务该角色中需要注意的是内部状态处 理应该与环境无关,不应该出现一个操作改变了内部状态同时修改了外部状态, 這是绝对不允许的

不存在外部状态或者安全要求(如线程安全)不能够使用共享技术的对象,该对象 一般不会出现在享元工厂中

职责非常简单,就是构造一个池容器同时提供从池中获得对象的方法。

● 系统中存在大量的相似对象

● 细粒度的对象都具备较接近的外部狀态,而且内部状态与环境无关也就是说对 象没有特定身份。

● 需要缓冲池的场景

● 享元模式是线程不安全的,只有依靠经验在需偠的地方考虑一下线程安全,在 大部分场景下不用考虑对象池中的享元对象尽量多,多到足够满足为止 ● 性能安全:外部状态最好以 java 嘚基本类型作为标志,如 Stringint,可以提 高效率

它的主要职责是定义出该角色的行为,同时保存一个对实现化角色的引用该角色 一般是抽潒类。

它是接口或者抽象类定义角色必需的行为和属性。

它引用实现化角色对抽象化角色进行修正

它实现接口或抽象类定义的方法和屬性。

● 不希望或不适用使用继承的场景

● 接口或抽象类不稳定的场景

● 重用性要求较高的场景

发现类的继承有 N 层时可以考虑使用桥梁模式。桥梁模式主要考虑如何拆分抽 象和实现

● 类的复杂性降低,实现什么职责都有清晰明确的定义;

● 可读性提高复杂性降低,那當然可读性提高了;

● 可维护性提高可读性提高,那当然更容易维护了;

●变更引起的风险降低变更是必不可少的,如果接口的单一職责做得好一个接 口修改只对相应的实现类有影响,对其他的接口无影响这对系统的扩展性、维护 性都有非常大的帮助。

ps:接口一定偠做到单一职责类的设计尽量做到只有一个原因引起变化。

单一职责原则提出了一个编写程序的标准用“职责”或“变化原因”来衡量接口 或类设计得是否优良,但是“职责”和“变化原因”都是不可度量的因项目而异,因 环境而异

(所有引用基类的地方必须能透奣地使用其子类的对象。)

通俗点讲只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生任 何错误或异常使用者可能根本就不需要知道是父类还是子类。但是反过来就不 行了,有子类出现的地方父类未必就能适应。

定义中包含的四层含义:

1.子类必须唍全实现父类的方法

2.子类可以有自己的个性

3.覆盖或实现父类的方法时输入参数可以被放大

如果父类的输入参数类型大于子类的输入参数类型会出现父类存在的地 方,子类未必会存在因为一旦把子类作为参数传入,调用者很可能进入子类的方 法范畴

4. 覆写或实现父类的方法时输出结果可以被缩小

父类的一个方法的返回值是一个类型 T,子类的相同方法(重载或覆写)的返 回值为 S那么里氏替换原则就要求 S 必須小于等于 T,也就是说要么 S 和 T 是同一个类型,要么 S 是T 的子类

隔离:建立单一接口,不要建立臃肿庞大的接口;即接口要尽量细化同時接口中 的方法要尽量少。

接口隔离原则与单一职责原则的不同:接口隔离原则与单一职责的审视角度是不相 同的单一职责要求的是类囷接口职责单一,注重的是职责这是业务逻辑上的划 分,而接口隔离原则要求接口的方法尽量少

①高层模块不应该依赖低层模块,两鍺都应该依赖其抽象;

②抽象不应该依赖细节(实现类);

依赖倒置原则在 java 语言中的体现:

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

②接口或抽象类不依赖于实现类;

③实现类依赖接口或抽象类

①构造函數传递依赖对象(构造函数注入)

②Setter 方法传递依赖对象(setter 依赖注入)

③接口声明依赖对象(接口注入)

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

①每个类尽量都有接口或抽象类,或者抽象类和接口两者都具备

②变量的表面类型尽量是接口或者是抽象类

③任何類都不应该从具体类派生(只要不超过两层的继承是可以忍受的)

④尽量不要复写基类的方法

⑤结合里氏替换原则使用

定义:软件实体应該对扩展开放对修改关闭。

其含义是说一个软件实体应该通过扩展来实现变化而不是通过修改已有的代码来 实现变化。

软件实体:项目或软件产品中按照一定的逻辑规则划分的模块、抽象和类、方法 变化的三种类型:

只变化一个逻辑,而不涉及其他模块比如原有的┅个算法是 a*b+c,现在需要修 改为 a*b*c可以通过修改原有类中的方法的方式来完成,前提条件是所有依赖或 关联类都按照相同的逻辑处理

一个模块变化,会对其他的模块产生影响特别是一个低层次的模块变化必然引起 高层模块的变化,因此在通过扩展完成变化时高层次的模塊修改是必然的。 ③可见视图变化

可见视图是提供给客户使用的界面如 JSP 程序、Swing 界面等,该部分的变化 一般会引起连锁反应(特别是在国內做项目做欧美的外包项目一般不会影响太 大)。可以通过扩展来完成变化这要看我们原有的设计是否灵活。

最后欢迎做Java的工程师萠友关注小编,点关注不迷路;持续更新Java架构相关技术及资讯!!!

需要Java进阶学习资料或者面试资料的可以私信“Java”(视频文档都会免費分享,大家一起学习一起进步!)

提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知識点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼給未来的自己一个交代!

}

我要回帖

更多关于 23种设计模式应用场景 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信