设计模式作为保证代码扩展性,易读性工具之一,也是面试必备考点之一,是需要程序员必须熟练掌握的技能之一,所以自己再读《设计模式之禅》,为提高学习质量遂写下数篇笔记,此篇为第一篇,主要讲为什么要用设计模式,以及设计模式的原则和分类,这篇文章仅仅是提及各种设计模式的基本概念,后续会陆续更新每一种设计模式的具体含义,应用场景及代码实现
一. 为什么要用设计模式?
- 设计模式是前人总结的经验
- 设计模式可以提高代码的可重用性
- 设计模式可以增强系统的可维护性
- 设计模式可以增强代码的可扩展性
- 设计模式可以提高系统的可阅读性
如果不仅仅想一直再一线码代码,有一个架构师的理想,想要站在更高层面看待软件开发,设计模式便是你必须要掌握的技能之一
二. 设计模式的6大设计原则
1 单一职责原则
有且仅有一个原因导致类的状态的变更,接口尽量做到单一职责,类的设计状态改变尽量只有一个原因
2 里氏替换原则
所有引用基类的地方必须能够透明的使用其子类的对象;只要父类出现的地方子类就可以出现,而且替换为子类不会产生任何错误或者异常,使用者根本不需要知道到底是子类还是父类。但是反过来就不行了,有子类出现的地方,父类未必就能适应
- A:子类必须完全实现父类的方法
- B:子类可以由自己“个性”
- C:覆盖或者实现父类的方法时输入参数可以被放大
- D:覆写或实现父类的方法时输出结果可以被缩小
3 依赖倒置原则
面向接口编程,应用到Java领域具体细则如下:
- A:模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系
- B:接口和抽象类不依赖于实现类
- C:实现类依赖接口或抽象类
具体到项目中实施中应该遵循以下几个原则 - A:每一个类尽量都有接口和抽象类,或者接口和抽象类都有
- B:变量的表面类型尽量是接口或者抽象类。
- C:任何类都不应该从具体类派生
- D:尽量不要覆写基类的方法
- E:结合里氏替换原则原则使用
4 接口隔离原则
客户端不应该依赖它不需要的接口;
具体的实施原则如下:
- A:接口尽量小
- B:接口要高内聚
尽量少公布public方法,接口是对外的承诺,承诺越少系统的开发月有利 - C:定制服务
- D:有限度的设计接口
具体到项目应用中实施的原则: - A:一个接口只服务一个子模块或业务逻辑
- B:通过业务逻辑压缩接口中的public方法
- C:已经污染的接口,尽量去修改,若变更的风险较大,则采用适配模式进行转化处理
- D:了解环境,拒绝盲从
5 迪米特原则
一个对象应该对其他对象有较少的了解,即类间解耦
具体的原则
- A:只和朋友交流
类与类之间的关系建立在类间的,而不是方法间的,因此一个方法尽量不引入一个类中不存在的对象。 - B:朋友之间也是有距离的
尽量不要对外公布太多public方法或者非静态的public变量,尽量内敛,多使用private,package-private,protected等访问权限 - C:是自己的就是自己的
如果一个方法放在本类中,既不增加类间关系,也对本类不产生负面影响,那就放置到本类中。 - D:谨慎使用Serializable
6 开闭原则
一个软件实体如类,模块,函数,应该对扩展开放,对修改关闭
为什么要坚持开闭原则?
- A:开闭原则对测试的影响
- 扩展修改可以减少测试工作量
- B:开闭原则可以提高程序的可复用性
- C:开闭原则可以提高程序的可维护性
- D:开闭原则是面向对象开发的要求
项目中如何使用? - A:抽象约束
- B:元数据控制模块的行为
- C:制定项目章程
- 约定优于配置
- D:封装变化
- 将相同的变化封装到同一个接口。
三. 设计模式的分类
经常提及的设计有23种,这23中设计模式按照其特点可依此分为创建型,结构型,行为型
3.1 创建型
创建型模式是用来创建对象的模式,抽象了实例化的过程,帮助一个系统独立于其他关联对象的创建、组合和表示方式。所有的创建型模式都有两个主要功能:
- 1.将系统所使用的具体类的信息封装起来
- 2.隐藏类的实例是如何被创建和组织的。外界对于这些对象只知道他们共同的接口,而不清楚其具体的实现细节。
1. 工厂模式
定义一个用户创建对象的接口,让子类决定具体实例化哪一个类。工厂方法使一个类的实例化延迟到其子类中。
2. 抽象工厂模式
为创建一组相关或者相互依赖的对象提供统一的接口,而且无需指定他们的具体类
3. 建造者模式
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
4. 原型模式
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
3.2 结构型
结构型模式讨论的是类和对象的结构,它采用继承机制来组合接口或实现(类结构型模式),或者通过组合一些对象实现新的功能(对象结构型模式)。这些结构型模式在某些方面具有很大的相似性,但侧重点各有不同。
1. 代理模式(Proxy)
为某一个对象提供一种代理对象已达到控制其他对象对这个对象访问的一种设计模式;代理分为:动态代理和静态代理,其中动态代理应用比较广泛:AOP编程模式就是基于动态代理实现的
2. 装饰模式
动态给对象增加一些额外的职责,
3. 适配器模式
将一个类的接口变换成客户端所期待的接口,从而使得原本接口不匹配不能在一起工作的两个类可以在一起工作
4. 组合模式
也叫作合成模式,将对象组合成树形结构以表示成“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性
5. 桥梁模式
又称桥接模式,将抽象和实现解耦,使得两者可以独立德变化
6. 外观模式
又称门面模式,要求一个子系统的外部与其内部的通信必须通过一个统一的对象进行,外观模式提供一个高层次的接口,使得子系统更加易于使用
7. 享元模式
对象池技术的重要实现方式,使用共享对象可有效的支持大量的细粒度的对象
3.3 行为型
行为型设计模式关注的是对象的行为即对象的方法,用来解决对象之间的依赖和联系问题。
1. 模板方法模式
定义一个操作中算法的框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
2. 命令模式
将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化;对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能
3. 责任链模式
使得多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止
4. 策略模式
定义一组算法,将每个算法都封装起来,并且使得他们之间可以互换
5. 迭代器模式
它提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节
6. 中介者模式
用一个中介对象封装一系列的对象交互,中介者使得个对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变他们之间的交互
7. 观察者模式
定义一个对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新
8. 备忘录模式
在不破坏封装性的前提下,捕获一个对象的内部状态并在该对象之外保存这个状态。这样以后就可将对象恢复到原先保存的状态
9. 访问者模式
封装一些作用于某种数据结构中的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。
10. 状态模式
当一个对象的内部状态改变时允许其改变行为,这个对象看起来像改变了其类;
11. 解释器模式
给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子
参考文献
《设计模式之禅》
设计模式-概念、要素、分类(00)
设计模式分类