设计模式及相关应用案例
设计模式
定义:
设计模式是一类问题的可复用的解决方案。 一般通过以下四个方面描述:
名称: 设计模式的名称;
待解问题: 要解决问题的何时运用这种模式,运行模式的上下文。
解决方案: 解决方案的抽象。
结论:这种方案的利弊, 主要描述方案弹性, 扩展性, 可移植性。
分类:
按照功能:
创建模式:对类实例化过程的抽象。
结构模式:将类或者对象进行组合。
行为模式:对象职责的划分及算法抽象。
按照实现:
类模式 : 继承方式实现,静态的
对象模式: 组合方式实现, 动态的。
常见设计模式:
简单工厂
通过Sorter工厂可以创建具体排序类, 排序类遵循interface接口。 如果要更换排序时, Client不需要进行变更只需要从Factory获取。
工厂模式本身不符合的开闭原则结果方案: 通过配置文件方式加载获得构造实现类的变更。
改进后的简单工厂模式: 修改排序算法时需要修改SortFactory违反了开闭原则OCP, 可以通过将使用的排序算法存放到配置文件方式, 再通过反射机制进行加载, 从而不需要修改Factory来实现构造实现类的变更。
单例模式
私有构造函数: 使得外部无法通过new创建实例,
静态方法:能通过类获取类实例
私有静态变量:使得类实例化创建惟一对象。
饿汉模式(推荐)
定义类时,单实例创建。
特点: 启动慢,引用快。
懒汉模式
获取实例的时创建对象,需要synchronized同步等待,防止并发处理异常。
特点: 启动快,引用慢。
适配器模式
对于现有接口, 现有的类不满足,可以通过适配器模式使得完成原有类满足接口功能的实现, 实现高层模块定义好的接口,把接口里的实现委托父类(继承方式)或者 成员变量(组合方式)实现
类适配器:
对象适配器:(推荐)
应用: JDBC Driver, JDBC-ODBC Bridge
JUnit中的设计模式
JUnit单元测试的步骤
初始化:setUp
清除环境:tearDown
书写测试方案: testXyz
模板方法
概念:
类的行为模式, 通过继承实现扩展积累确定号具体流程, 子类实现。
实现方法:
抽象方法:(推荐)子类强制实现
具体方法: 可以选择覆盖
钩子方法: 父类不实现,子类选择覆盖。
策略模式
概念:
对象的行为模式,通过组合方法来实现扩展。
使用场景:
重构系统:将条件语句转化未策略的多态调用, 通过工厂产生需要的策略模式。
策略模式与模板结合使用:JUnit
JUnit调用策略接口Test接口 , 模板方法定义在TestCase中定义, 具体实现类继承TestCase, 按照具体的模板定义方法进行实现。
组合模式
概念:
对象的结构模式。很多情况先用于树形结构的数据上。 如文件系统或AWT控件。
装饰器模式
概念:
对象结构模式, 不改变客户端接口前提下,扩展现有对象, 如果要与装饰的对象使用统一接口,可以互相装饰。
相关应用:
Java Servlet, Java I/O 类库,同步化装饰 Collections.synchronizedList
Spring中的设计模式
依赖注入DI 控制反转IoC
A依赖B对象, A对象要构建B对象, 依赖注入,A对象不用创建B对象, B对象由外部创建,注入到A对象中。
Spring通过配置文件, 配置相关Bean结构信息,设置依赖对象,构建注入对象。 步骤如下:
获取Class对象。
直接调用无参数构造函数,实例化一个对象。
获取属性节点,调用setter方法设置属性。
获取属性名,S属性。
构造Setter方法, 获取Setter的Method对象。
调用Setter设置对象属性。
单例模式
由于Spring中容器管理的对象的创建, 单例实现上存在一个HashMap, 实现的缓存并保证唯一性。 步骤如下:
检查缓存是否存在实例。 有直接反馈。
如果空,锁定全局变量进行处理, 调用工厂getObject并更新到缓存。
Spring MVC模式
原有流程: 通过xml配置, url 匹配到具体的servlet, 当url匹配调用对应的servlet执行, sevrlet获得是容器,request对象获取其中数据, 处理完后构建html,通过response,进行输出。
Spring流程:大致流程没有很大变化, 处理过程有Spring框架完成, 使用Spring DispatcherServlet进行分发和处理。
实际案例
代码重构案例: Hive 支持标准SQL的案例
职责拆分
transformer:实现sql语法点的转换sqlAST, 同时不同的语法点进行更细维度的拆分。
generator:将sqlAST转为Hive能够支持的AST结构树
将复杂的操作转为相对简单步骤,
设计模式的应用
装饰模式:SqlASTTransformer的构造, 每个Transforms用其他Transforms进行装饰。
每个语法点会被其他Transforms进行语法检查。
模板方法:
子类实现tranform方法,被父类的tranformAST调用,在父类中输出相关日志和时间。
ASTgenerate 通用用到了模板方法。
参考及引用
架构师训练营作业-李智慧老师相关讲义
Photo by Keith Lobo from Pexels
评论