《设计模式Java版》读书笔记
- 源码下载地址:https://github.com/quanke/design-pattern-java-source-code.git
面向对象设计原则
-
7种常用的面向对象设计原则
-
单一职责原则 (Single Responsibility Principle, SRP) 一个类只负责一个功能领域中的相应职责
-
开闭原则 (Open-Closed Principle, OCP) 软件实体应对扩展开放,而对修改关闭
-
里氏代换原则 (Liskov Substitution Principle, LSP)所有引用基类对象的地方能够透明地使用其子类的对象
-
依赖倒转原则 (Dependence Inversion Principle, DIP) 抽象不应该依赖于细节,细节应该依赖于抽象
-
接口隔离原则 (Interface Segregation Principle, ISP) 使用多个专门的接口,而不使用单一的总接口
-
合成复用原则 (Composite Reuse Principle, CRP) 尽量使用对象组合,而不是继承来达到复用的目的
-
迪米特法则 (Law of Demeter, LoD) 一个软件实体应当尽可能少地与其他实体发生相互作用
里氏代换原则
-
里氏代换原则
-
基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来则不成立
-
尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。
依赖倒转原则
-
依赖倒转原则
-
实现依赖倒转原则时,我们需要针对抽象层编程,而将具体类的对象通过依赖注入(DependencyInjection, DI)的方式注入到其他对象中,依赖注入是指当一个对象要与其他对象发生依赖关系时,通过抽象来注入所依赖的对象。常用的注入方式有三种,分别是:构造注入,设值注入(Setter注入)和接口注入。
接口隔离原则
- 接口隔离原则,当一个接口太大时,我们需要将它分割成一些更细小的接口
合成复用原则
-
合成复用原则
-
尽量使用对象组合,而不是继承来达到复用的目的。
-
复用时要尽量使用组合/聚合关系(关联关系),少用继承
-
首先应该考虑使用组合/聚合,组合/聚合可以使系统更加灵活,降低类与类之间的耦合度,一个类的变化对其他类造成的影响相对较少
-
通过继承来进行复用的主要问题在于继承复用会破坏系统的封装性,因为继承会将基类的实现细节暴露给子类
-
如果两个类之间是“Has-A”的关系应使用组合或聚合,如果是“Is-A”关系可使用继承。“Is-A”是严格的分类学意义上的定义,意思是一个类是另一个类的”一种”;而”Has-A”则不同,它表示某一个角色具有某一项责任。
迪米特法则
-
迪米特法则
-
一个软件实体应当尽可能少地与其他实体发生相互作用
-
迪米特法则还有几种定义形式,包括:不要和“陌生人”说话、只与你的直接朋友通信等
-
引入一个合理的第三者来降低现有对象之间的耦合度
工厂三兄弟之简单工厂模式
工厂三兄弟之工厂方法模式
-
工厂方法模式中,我们不再提供一个统一的工厂类来创建所有的产品对象,而是针对不同的产品提供不同的工厂,系统提供一个与产品等级结构对应的工厂等级结构。
-
图3 日志记录器结构图
-
在抽象工厂模式中,增加新的产品族很方便,但是增加新的产品等级结构很麻烦?
确保对象的唯一性——单例模式
-
确保对象的唯一性——单例模式
-
构造函数改为private修饰
-
为了保证成员变量的封装性,我们将TaskManager类型的tm对象的可见性设置为privat
-
getInstance()方法的修饰符,首先它应该是一个public方法,以便供外界其他对象使用,其次它使用了static关键字,即它是一个静态方法,在类外可以直接通过类名来访问,而无须创建TaskManager对象
对象的克隆——原型模式
-
对象的克隆——原型模式
-
所创建的对象是全新的对象,它们在内存中拥有新的地址
-
一个克隆对象都是相互独立的。通过不同的方式修改可以得到一系列相似但不完全相同的对象。
? 不能, return this 的话, 那么就是返回的同一个对象, 原型是返回一个新的对象
-
思考能否将上述代码中的clone()方法写成:public Prototype clone() { return this;}出你的理由
-
一般而言,Java语言中的clone()方法满足:(1) 对任何对象x,都有x.clone() != x,即克隆对象与原型对象不是同一个对象;(2) 对任何对象x,都有x.clone().getClass() == x.getClass(),即克隆对象与原型对象的类型一样;(3) 如果对象x的equals()方法定义恰当,那么x.clone().equals(x)应该成立。为了获取对象的一份拷贝,我们可以直接利用Object类的clone()方法,具体步骤如下:(1) 在派生类中覆盖基类的clone()方法,并声明为public;(2) 在派生类的clone()方法中,调用super.clone();(3)派生类需实现Cloneable接口。
-
浅克隆和深克隆的主要区别在于是否支持引用类型的成员变量的复制
-
在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制
-
通过覆盖Object类的clone()方法可以实现浅克隆
-
深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象
-
在Java语言中,如果需要实现深克隆,可以通过序列化(Serialization)等方式来实现
-
原型模式总结
-
主要优点
-
当创建新的对象实例较为复杂时,使用原型模式可以简化对象的创建过程,通过复制一个已有实例可以提高新实例的创建效率
-
可以使用深克隆的方式保存对象的状态,使用原型模式将对象复制一份并将其状态保存起来,以便在需要的时候使用(如恢复到某一历史状态),可辅助实现撤销操作。
复杂对象的组装与创建——建造者模式
- 复杂对象的组装与创建——建造者模式
- 建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
- 它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。建造者模式结构如图8-2所示:
-
类适配器模式中适配器和适配者是继承关系,类适配器模式结构如图9-5所示
-
桥接模式用一种巧妙的方式处理多层继承存在的问题,用抽象关联取代了传统的多层继承,将类之间的静态继承关系转换为动态的对象组合关系,使得系统更加灵活,并易于扩展,同时有效控制了系统中类的个数
-
结构示意图如图10-4所示
-
适配器模式通常用于现有系统与第三方产品功能的集成,采用增加适配器的方式将第三方类集成到系统中
-
如图10-6所示
-
如图11-4所示
扩展系统功能——装饰模式
-
扩展系统功能——装饰模式
-
Sunny软件公司基于面向对象技术开发了一套图形界面构件库VisualComponent,该构件库提供了大量基本构件,如窗体、文本框、列表框等,由于在使用该构件库时,用户经常要求定制一些特效显示效果,如带滚动条的窗体、带黑色边框的文本框、既带滚动条又带黑色边框的列表框等等,因此经常需要对该构件库进行扩展以增强其功能
-
图12-2
-
装饰模式是一种用于替代继承的技术,它通过一种无须定义子类的方式来给对象动态增加职责,使用对象之间的关联关系取代类之间的继承关系
-
如果我们希望得到一个既有滚动条又有黑色边框的窗体,不需要对原有类库进行任何修改,只需将客户端代码修改为如下所示:
-
class Client { public static void main(String args[
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!