designpatterns;discipline
2018-06-19 10:27:33 11 举报
AI智能生成
对java开发中的设计原则和设计模式的总结
作者其他创作
大纲/内容
desigin pattens
行为型模式,共十一种
策略模式
定义
定义一系列算法,把他们一个个封装起来,并且使他们可以互相替换。
本质
分离算法,选择实现
类图
原则体现
开闭原则
里氏替换原则
使用场景
需要封装算法的时候
使用示例
Compare接口
状态模式
定义
允许一个对象在其内部状态改变时改变他的行为
本质
根据状态来分离和选择行为
类图
原则体现
使用场景
行为取决于状态时
一个操作语句中包含庞大的分支语句时
使用示例
模板方法模式
定义
定义一个操作中的算法和骨架,而将一些步骤延迟到子类中。模板方法使得子类可以再不改变一个算法的结构即可重定义该算法的某些特定步骤
本质
固定算法和骨架
类图
原则体现
开闭原则
里氏替换原则
使用场景
定义算法骨架
抽取公共行为
使用示例
Compare()接口 spring的JDBC模板
责任链模式
定义
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条连传递该请求,直到有一个对象处理它位置
本质
分离职责,动态组合
类图
原则体现
使用场景
多个对象处理一个请求,但是具体由哪个对象来处理,是运行时动态决定的
没有明确指定接收者的情况
动态指定处理者
使用示例
过滤器
观察者模式
定义
定义对象间的一种一对多的依赖关系。当一个对象的状态发生改变时,所有依赖于他的对象都得到通知并自动更新
本质
触发联动
类图
原则体现
使用场景
需要联动的时候
使用示例
使用websocket做聊天室功能的时候,监听
迭代子模式
定义
提供一种方法顺序的访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示
本质
控制访问聚合对象中的元素
类图
原则体现
使用场景
访问一个聚合对象又不想暴露他的内部表示
希望多种方式遍历聚合对象
用同一种方式遍历不同的聚合对象
使用示例
Collection接口的继承类的迭代器
命令模式
定义
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作
本质
封装请求
类图
原则体现
使用场景
如果需要抽象出需要执行的动作,并参数化这些对象
如果需要在不同的时刻指定、排列、和执行请求
如果需要支持取消操作
如果需要恢复操作
在需要事物的系统中,可以选用命令模式
使用示例
- java.lang.Runnable
访问者模式
定义
表示一个作用于某对象结构中的各元素的操作。他使你可以再不改变各元素的类的前提下作用于这些元素的新操作
本质
预留通路,回调实现
类图
原则体现
如果想对一个类结构中的各个元素进行很多不同的而且不相关的操作,为了避免这些操作是类变得复杂,可以使用访问者模式。把这些操作分散到不同的访问者对象中去,每个访问者对象实现同一类功能
使用场景
使用示例
- javax.lang.model.element.Element and javax.lang.model.element.ElementVisitor
中介者模式
定义
用一个中介对象来封装一系列的对象交互。中介者使得各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变他们时间的交互
本质
封装交互
类图
原则体现
使用场景
两个对象之间通信比较复杂
一个对象引用很多对象,并直接跟这些对象交互
使用示例
比如两个业务类,操作上有联动关系,可以使用中介者模式
解释器模式
定义
给定一个语言,定义他的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子
本质
分离实现,解释执行
类图
原则体现
使用场景
当一个语言需要解释执行,并且可以将语言中的句子表示为一个抽象语法书的时候,可以考虑使用解释器模式
使用示例
备忘录模式
定义
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态
本质
保存和恢复内部状态
类图
原则体现
使用场景
需要保存对象某一个时刻的全部状态
需要保存对象的内部状态
使用示例
- java.util.Date
- java.io.Serializable
结构型模式,共七种
适配器模式
定义
将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能在一起工作的那些类可以一起工作。
本质
转化匹配,复用功能
类图
原则体现
使用场景
使用已存在的类,但是这个类不符合使用规则,可以通过适配实现
使用示例
装饰器模式
定义
动态地给一个对象添加一些额外的职责。
本质
动态组合
类图
原则体现
使用场景
不影响原来类的职责,动态透明的条件职责
使用示例
组合模式
定义
将对象组合成属性结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合的使用具有一致性
本质
统一叶子对象和组合对象
类图
原则体现
使用场景
如果想表示部分-整体的层次结构,同一整体和部分的操作
同一使用组合结构中的所有对象
使用示例
代理模式
定义
为其他对象提供一种代理以控制对这个对象的访问
本质
控制对象访问
类图
原则体现
使用场景
使用示例
jdk动态代理
外观模式
定义
为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易只用
本质
封装交互,简化调用
类图
原则体现
最少知道原则
使用场景
为子系统提供一个简单的接口
使用示例
桥接模式
定义
将抽象部分和实现部分分离,使他们都可以独立地变化
本质
分离抽象和实现
类图
原则体现
开闭原则,多用组合少用解除
使用场景
使用示例
jdbc中获取驱动,通过DriverManage实现
享元模式
定义
通过共享技术有效地支持大量细粒度对象
本质
分离与共享
类图
原则体现
使用场景
如果程序中使用了大量的细粒度对象
使用示例
Integer这个类使用了享元模式
创建型模式,共五种
工厂方法模式
定义
定义一个用于创建对象的接口,让子类决定实例化那一个类,工厂方法使一个类的实例化延迟到其子类
本质
延迟到子类来选择实现
类图
原则体现
依赖导致原则
使用场景
如果一个类需要创建某个接口的对象,但是又不知道具体的实现,这种情况可以选用工厂方法模式,把创建对象的工作延迟到子类中去实现
如果一个类本身就需要他的子类来创建所需的对象的时候,应该使用工厂方法模式
使用示例
Collecton接口中的迭代器
抽象工厂模式
定义
提供一个创建一系列相关或相互依赖的对象的接口,而无需指定他们具体的类
本质
选择产品族的实现
类图
原则体现
开闭原则
使用场景
如果希望一个系统独立于他的产品对象的创建、组合和表示的时候。换句话说,希望一个系统知识知道产品的接口,而不关心实现的时候
如果一个系统要有多个产品系列中的一个来配置的时候。换句话说,就是可以动态地切换产品族的时候
如果要强调一系列相关产品的接口,以便联合使用它们的时候
使用示例
DriverManager.getConnection()方法中的返回的Connection,就是一个抽象工厂,这个工厂中包含多种对象
单例模式
定义
保证一个类仅有一个实例,并提供一个访问它的全局访问点
本质
控制示例数量
建造者模式
定义
将一个复杂的构建和他的表示分离,使得同样的构建过程可以创建不同的表示
本质
分离整体构建算法和部件构造
类图
原则体现
使用场景
如果创建对象的算法,应该独立于该对象的组成部分以及他们的装配方式时
如果同一个构建过程有着不同的表现时
使用示例
StringBuilder是String这个产品的构建起,不是标准的,同样StringBuffer也是一种构建方式
子主题
原型模式
定义
用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象
本质
克隆生成对象
类图
原则体现
使用场景
如果一个系统想要独立于它想要使用的对象时
如果需要实例化的类是在运行时刻动态指定
使用示例
desigin discipline
单一原则
定义
不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责
问题由来
类T负责两个不同的职责:职责P1,职责P2。当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障
解决方案
遵循单一职责原则。分别建立两个类T1、T2,使T1完成职责P1功能,T2完成职责P2功能。这样,当修改类T1时,不会使职责P2发生故障风险;同理,当修改T2时,也不会使职责P1发生故障风险
优点
- 可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;
- 提高类的可读性,提高系统的可维护性;
- 变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。
里氏替换原则
定义1
如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型
定义2
所有引用基类的地方必须能透明地使用其子类的对象。
里氏替换原则通俗的来讲就是
- 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
- 子类中可以增加自己特有的方法。
- 当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
- 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。
问题由来
有一功能P1,由类A完成。现需要将功能P1进行扩展,扩展后的功能为P,其中P由原有功能P1与新功能P2组成。新功能P由类A的子类B来完成,则子类B在完成新功能P2的同时,有可能会导致原有功能P1发生故障
解决方案
当使用继承时,遵循里氏替换原则。类B继承类A时,除添加新的方法完成新增功能P2外,尽量不要重写父类A的方法,也尽量不要重载父类A的方法
依赖倒置原则
定义
高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象
问题由来
类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成。这种场景下,类A一般是高层模块,负责复杂的业务逻辑;类B和类C是低层模块,负责基本的原子操作;假如修改类A,会给程序带来不必要的风险
解决方案
将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I间接与类B或者类C发生联系,则会大大降低修改类A的几率
接口隔离原则
定义
客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。
问题由来
类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对于类A和类B来说不是最小接口,则类B和类D必须去实现他们不需要的方法
解决方案
将臃肿的接口I拆分为独立的几个接口,类A和类C分别与他们需要的接口建立依赖关系。也就是采用接口隔离原则
迪米特法则 最少知道原则 低耦合,高内聚
定义
一个对象应该对其他对象保持最少的了解
问题由来
类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大
解决方案
尽量降低类与类之间的耦合
开闭原则
定义
个软件实体如类、模块和函数应该对扩展开放,对修改关闭
问题由来
在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试
解决方案
当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化
0 条评论
下一页