设计模式
2021-11-21 19:43:24 0 举报
设计模式定义,SOLID原则, 创建型模式:工厂模式,建造者模式,原型模式 结构型模式:享元模式,门面模式,适配器模式,装饰者模式,组合模式 行为型模式:观察者模式
作者其他创作
大纲/内容
定义
在软件设计中,被反复使用的代码设计经验,目的是提高系统的可维护性和扩展性
原则(SOLID)
单一职责原则Single Responsibility Principle(SRP)
定义
一个类应该只有一个变化的原因
开闭原则Open Closed Principle(OCP)
定义
对扩展开发,对修改关闭
里氏替换原则Liskov Substitution Principle(LSP)
定义
所有引用基类的地方必须能透明地替换成子类
依赖倒置原则Interface Segregation Principle(ISP)
定义
高层模块不应该依赖底层模块,二者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象
接口隔离原则Dependence Inversion Principle(DIP)
定义
客户端不应该依赖它不需要的接口,对一个类的依赖应该建立在最小接口上
和单一职责的区别
单一职责强调职责隔离,针对具体实现类,接口隔离原则强调接口规范设计
迪米特法则(最少知道原则)
定义
一个对象应该对其他对象保持最少的了解
实现
只与直接朋友通信,不与陌生人通信
陌生的类不要出现以局部变量的形式中出现在类的内部
创建型模式
单例模式
工厂方法
定义
定义一个创建对象的接口,让子类决定实例化哪个类,使对象的创建延迟到子类
场景
当一个类不知道它所必须创建的对象的类的时候
当一个类希望由它的子类指定它所创建的类的时候
抽象工厂模式
定义:提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类
场景
程序需要处理不同系列的相关的产品,但又不希望依赖其中具体的实现类时
优点
可以确信从工厂得到的产品是彼此兼容的
避免具体产品与客户端代码的紧密耦合
单一职责原则
开闭原则
应用
java.sql.connection
java.sql.driver
建造者模式
定义:将一个复杂对象与它的表示分离,使同样的构建过程可以创建不同的表示
场景
建造复杂对象
对象的字段有依赖关系
不可变对象
优点
建造者独立,易扩展,开闭原则
便于控制细节风险
应用
spring的RequestMappingInfo
BeanDefinitionBuilder
原型模式
定义
使用原型指定待创建对象的类型,并通过复制这个原型来创建新的对象
实现方式
实现Cloneable接口,重写Object.clone()
序列化机制
应用场景
当代码不需要依赖复制对象的具体类的时候
优点
可以在不耦合具体类的情况下复制对象
避免重复的对象创建代码
更方便的创建复杂对象
结构型模式
享元模式
定义
运用共享技术来支持大量细粒度的对象
场景
如果系统中有大量相同类型的不可变对象,那么可以将它们缓存起来,避免重复创建占用CPU和内存资源
应用
包装类型缓存
String字符串常量池
数据库缓存
优点
避免了大量对象的重复创建,节省系统资源,提高响应速度
门面(外观)模式
定义
为子系统的一组接口提供一个一致的界面,Facade模式定义了一个简单的视图,使得子系统更容易使用
场景
微服务网关
优点
减少了客户需要交互的子系统数量,简化了子系统的使用
客户端不与具体子系统耦合,而是与门面耦合,可以较为方便的升级子系统而尽量不影响客户端
适配器模式
定义
将一个类的接口转换为客户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
是一种补救措施
场景
复用一个控制之外的原有对象,但接口与复用环境不一致
通常在维护阶段,不太容易修改的时候使用
设计之初,如果要用第三方组件,但接口不兼容,又不好修改自身接口
装饰者模式
定义
在不改变原有类的基础上,将功能附加到对象上,就修改来说,比生成子类更加灵活
参与者
优点
相比于静态继承,可以在运行期动态添加和删除职责
继承需要为每个职责添加一个子类,避免了继承体系的臃肿
为一个Component提供多个Decorator,这使得你可以对职责进行混合和匹配
缺点
产生许多相似的小对象,很难学习这个系统,难以排错
注意
接口一致性,装饰和组件应该有一个公共的父类
省略抽象的Decorator,如果只有一个ConcreateDecorator
接口简单性
组件过于庞大时,装饰者代价太高,可以考虑策略模式
和strategy的区别
decorator模式,装饰者对组件是透明的,组件不需要了解装饰者
strategy,组件知道可以对自己的哪些行为进行扩充,因此它必须引用并维护相应的策略
装饰者必须与组件有公共的接口,策略不需要
与适配器的区别
装饰者只改变对象的职责,而不改变接口,适配器提供了全新的接口
组合模式
定义
将对象组合成树形结构以表示“部分-整体”的关系,使得用户对单个对象和组合对象的使用具有一致性
实现
优缺点
简化客户端代码
更容易添加新的组件
不好限制组合中组件的类型,只能在运行时检查
行为型模式
观察者模式(发布-订阅模式)
定义了一种一对多的对象依赖关系,当一个对象的状态发生改变,关联的对象都得到通知并被自动更新
一个目标可以有任意数目的观察者,它发出通知时并不需要知道它的具体观察者是谁
参与者
目标Subject
目标知道它的观察者,可以有任意多个观察者
提供注册和删除观察者的接口, 以及一个通知接口notify
观察者Observer
提供一个目标发出通知时更新自身的接口update
ConcreteSubject
具体目标存储了各自的状态,并在状态发生改变时通知与其关联的观察者
ConcreteObserver
维护了它关联的Subject的引用,和相应的状态,并提供一个更新方法以保持自身状态与目标状态一致
观察者通过查询目标的状态,来更新自己的状态
目标状态的变化可以由其中一个观察者发出,观察者先不更新自身状态,而是先更新目标状态,从而调用notify方法更新所有观察者的状态
优缺点
支持广播通信,目标发送通知不需要指定它的接收者,通知被自动广播给已向该目标注册的所有观察者,可以在任意时刻增加和删除观察者,处理一个通知取决于观察者
缺点:因为一个观察者不知道其他观察者的存在,它对目标的更新可能会引起一系列对观察者以及相关联对象的更新,如果依赖准则处理不当可能会引起错误的更新
实现
如果目标很多,观察者很少,为了避免每个目标都维护对应观察者的引用造成空间浪费,可以用hash表维护目标到观察者的映射,这样没有观察者的目标就不占用任何存储空间
观察者可以观察多个目标,这样的话update方法的参数就要加目标参数,以便知道是哪个目标状态更新了。或者提供一个获取状态更新的目标集合的方法,比如NIO selector
调用notify的时机: 1、目标每次状态更新都触发一次notify通知,这样客户端使用简单,但是容易导致频繁通知。2、由客户端调用notify,这样不会导致不必要的通知,但增加了使用难度,可能会遗漏触发通知
通知的时候要注意,必须在目标状态一致时通知
通知的方式有推模式和拉模式
推模型
目标向观察者发送更新的状态信息,通常是在update参数中定义
需要目标假定观察者需要哪些信息,这使得观察者可能难以复用
拉模型
目标只告诉观察者状态更新了,具体更新信息需要观察者再向目标查询获得
强调的是目标不知道它的观察者,观察者更易于扩展,但效率较差,因为观察者需要在没有目标帮助的情况下获取什么状态改变了
为了提高更新的效率,可以在注册观察者时指定它感兴趣的事件,notify方法参数增加事件参数,特定事件触发时,只通知对事件感兴趣的观察者
0 条评论
下一页