设计模式之禅

《设计模式之禅》之备忘录模式

强颜欢笑 提交于 2020-04-04 13:26:56
一、备忘录模式的定义 备忘录模式提供了一种弥补真实世界缺陷的方法,让”后悔药”在程序的世界中真实可行,其定义如下: 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。 通用类(三个角色) Originator发起人角色 记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据。 Memento备忘录角色 负责存储Originator发起人对象的内部状态,在需要的时候提供发起人需要的内部状态。 Caretaker备忘录管理员角色 对备忘录进行管理、保存和提供备忘录。 二、备忘录模式的应用 1.备忘录模式的使用场景 需要保存和恢复数据的相关状态场景。 提供一个可回滚的操作;比如Word中的Ctrl+Z组合键,IE浏览器中的后退按钮,文件管理器上的backspace键等。 需要监控的副本场景中。例如要监控一个对象的属性,但是监控又不应该作为系统的主业务来调用,它只是边缘应用,即使出现监控不准,错误报警也影响不大,因此一般的做法是备份一个主线程中的对象,然后由分析程序来分析。 数据库连接的事务管理就是用的备忘录模式。 2.备忘录模式的注意事项 (1)备忘录的生命期 备忘录创建出来就要在”最近”的代码中使用,要主动管理它的生命周期,建立就要使用,不使用就要立刻删除其引用,等待垃圾回收器对它的回收处理。

《设计模式之禅》六大设计原则2

北城以北 提交于 2020-03-21 21:16:17
接口隔离原则 接口隔离原则的定义 接口分为两种: ● 实例接口(Object Interface),在Java中声明一个类,然后用new关键字产生一个实 例,它是对一个类型的事物的描述,这是一种接口。 Java中的类也是一种接口。 ● 类接口(Class Interface),Java中经常使用的interface关键字定义的接口。 那什么是 隔离 呢?它有两种定义,如下所示: ● 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 interface. (类间的依赖关系应该建立在最小的接口上。) 可以把这两个定义概括为一句话:建立单一接口,不要建立臃肿庞大的接口。再通 俗一点讲:接口尽量细化。 接口隔离原则是对接口进行规范约束,其包含以下 4层含义: ● 接口要尽量小, 但是 “小”是有限度 的,首先就是不能违反单一职责原则 根据接口隔离原则拆分接口时,首先必须满足单一职责原则。 ● 接口要高内聚 什么是高内聚?高内聚就是提高接口、类、模块的处理能力,减少对外的交互。

《设计模式》——迪米特法则

拥有回忆 提交于 2020-03-11 10:07:25
定义   其实《设计模式之禅》关于原则的部分,我最喜欢的就是《迪米特法则》没什么特殊原因,前段时间部门培训,让我出个培训内容,就是选择的迪米特法则。其实原因很简单,就因为看它名字都不知道究竟是拿来干啥的。 先臭美一下 《设计模式》——目录 ,然后让我们进入正题。   所以究竟什么是迪米特法则呢?   迪米特法则(Law of Demeter,LoD)也称为最少知识原则(Least Knowledge Principle,LKP),虽然名字不同,但描述的是同一个规则:一个对象应该对其他对象有最少的了解。通俗地讲,一个类应该对自己需要耦合或调用的类知道得最少,你(被耦合或调用的类)的内部是如何复杂都和我没关系,那是你的事情,我就知道你提供的这么多public方法,我就调用这么多,其他的我一概不关心。   对于这个定义说实话我还是挺喜欢的,但也是生活中我很难做到的一点,那就是“我就调用这么多,其他的我一概不关心”。其实在小的公司,这样的性格是不好的,毕竟很难做到一个萝卜一个坑,大家或多或少都需要承担一些职能外的任务。而且从个人成长的角度来说,其实也是参与越多,收获也会越多。    有感一段废话,可以跳过不看。职场中有一种情况,那就是A只做十件事,而且十件事都完成的很好;而B需要做一百件事,但是有一件事没有做好。这两个人谁的年终评估会更高一些呢?当然,这里不是劝大家“各人自扫门前雪

《设计模式之禅》之建造者模式

别等时光非礼了梦想. 提交于 2019-12-05 11:32:35
一、建造者模式的定义 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 二、建造者模式的应用 1.建造者模式的优点 (1)封装性 使用建造者模式可以使客户端不必知道产品内部组成的细节,如例子中我们就不需要关心每一个具体的模型内部是如何实现的,产生的对象类型就是CarModel。 (2)建造者独立,容易扩展 BenzBuilder和BMWBuidler是相互独立的,对系统的扩展非常有利。 (3)便于控制细节风险 由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。 2.建造者模式的使用场景 相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式; 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,则可以使用该模式; 产品类非常复杂,或者产品类中的调用顺序不同产生不同的效能,这个时候使用建造者模式非常合适; 在对象创建过程中会使用系统中的一些其他对象,这些对象在产品对象的创建过程中不易得到时,也可以采用建造者模式封装该对象的创建过程。这种场景只能是一个补偿方法,因为一个对象不容易获得,而在设计阶段竟然没有发觉,而要通过创建者模式柔化创建过程,本身已经违反设计的最初目标; 3.建造者模式的注意事项 建造者模式关注的是零件类型和装配工艺(顺序),这是它与工厂方法模式最大不同的地方,虽然同为创建类模式

《设计模式之禅》之抽象工厂模式

99封情书 提交于 2019-12-04 04:18:12
一、抽象工厂模式的定义 为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类。 二、抽象工厂模式的应用 1.抽象工厂模式的优点 封装性 ,每个产品的实现类不是高层模块要关心的,它要关心的是什么?是接口,是抽象,它不关心对象是如何创建出来的,这由谁负责呢?工厂类,只要知道工厂类是谁,我就能创建出一个需要的对象,省时省力,优秀设计就应该如此; 产品族内的约束为非公开状态 。例如生产男女比例的问题上,猜想女娲娘娘肯定有自己的打算,不能让女盛男衰,否则女性的优点不就体现不出来了吗?那在抽象工厂模式,就应该有这样的约束:每生产1个女性,就同时生产出1.2个男性,这样的生产过程对调用工厂类的高层模块来说是透明的,它不需要知道这个约束,我就是要一个黄色女性产品就可以,具体的产品族内的约束是在工厂内实现的; 2.抽象工厂模式的缺点 抽象工厂模式的最大缺点就产品族 扩展非常困难 ,为什么这么说呢?我们以通用代码为例,如果要增加一个产品C,也就是说产品家族由原来的2个增加到3个,抽象类AbstractCreator要增加一个方法createProductC(),然后两个实现类毒药修改,想想看,这严重违背了开闭原则,而且我们一直说明抽象类和接口是一个契约。改变契约,所有与契约有关系的代码都要修改,那么这段代码叫有毒代码,只要与这段代码有关系,就可能产生侵害的危险。 3

《设计模式之禅》之六大设计原则中篇

给你一囗甜甜゛ 提交于 2019-12-03 13:48:38
本文主要讲依赖倒置原则和接口隔离原则。 一、依赖倒置原则 1.定义 高层模块不应该依赖低层模块,两者都应该依赖其抽象; 抽象不应该依赖细节; 细节应该依赖于抽象; 高层模块和低层模块容易理解,每一个逻辑的实现都是由原子逻辑组成的,不可分割的原子逻辑就是低层模块,原子逻辑的再组装就是高层模块。 那什么是抽象?什么又是细节呢? 在Java语言中,抽象就是指接口或抽象类,两者都不能直接被实例化;细节就是实现类,实现接口或者继承抽象类而产生的类就是细节,其特点是可以直接被实例化,也就是可以加上一个关键字new产生一个对象。 在Java语言中的表现就是: 模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象产生的; 接口或抽象类不依赖于实现类; 实现类依赖接口或抽象类; 采用依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起的风险,提高代码的可读性和可维护性。 注意:设计是否具备稳定性,只要适当地”松松土”,观察”设计的蓝图”是否还可以茁壮地成长就可以得出结论,稳定性较高的设计,在周围环境频繁变化的时候,依然可以做到”我自岿然不动”。 2.依赖的三种写法 (1)构造函数传递依赖对象 在类中通过构造函数声明依赖对象,按照依赖注入的说法,这种方式叫做构造函数注入。 (2)Setter方法传递依赖对象 在抽象中设置etter方法声明依赖关系

策略模式原来这么简单!

僤鯓⒐⒋嵵緔 提交于 2019-11-29 10:46:16
前言 只有光头才能变强 回顾前面: 给女朋友讲解什么是代理模式 包装模式就是这么简单啦 单例模式你会几种写法? 工厂模式理解了没有? 无论是面试还是个人的提升,设计模式是必学的。今天来讲解 策略 模式~ 一、策略模式介绍 我一次听到策略模式这个词,是在我初学JDBC的时候。不知道大家有没有用过DBUtils这个组件。当时初学跟着视频学习,方立勋老师首先是让我们先自己封装一下JDBC的一些常用的操作(实际上就是模仿DBUtils这个组件)。 当时候的问题是这样的:我们打算封装一下 query() 查询方法,传入的参数有 String sql , Object[] objects (指定SQL语句和对应的参数)。我们想根据 不同的业务 返回不同的值。 比如说,有的时候我们返回的是一条数据,那我们想将这条数据封装成一个Bean对象 比如说,有的时候我们返回的是多条数据,那我们想将这多条数据封装成一个 List<Bean> 集合 比如说,有的时候我们返回的是xxxx数据,那我们想将这多条数据封装成一个 Map<Bean> 集合 ........等等等 当时解决方案是这样的: 先定义一个接口:ResultSetHandler( 调用者想要对结果集进行什么操作,只要实现这个接口即可 ) 这个接口定义了行为。 Object hanlder(ResultSet resultSet);