极客大学架构师训练营 框架开发 模式与重构 JUnit、Spring、Hive 核心源码解析 第 6 课
说明
讲师:李智慧
JUnit 中的设计模式
如何写单元测试
实现一个单元测试的步骤
创建测试类, 从 TestCase 派生
初始化
覆盖基类的方法:
protected void setUp()
消除环境
覆盖基类的方法:
protected void tearDown()
书写测试方法
命名规则:
public void testXyz()
JUnit 单元测试是如何执行的?
JUnit 单元测试的执行
Idea 中运行单元测试通过的图片。

JUnit 单元测试的执行时序图

这里用到了三个策略模式:
Eclipse定义了接口,策略的接口,策略的实现。定义一个plugin的规范。显示有多少个用例通过,多少个用例失败。
Eclipse 调用runBare方法,调用TestCase。
TestCase只有一个,实现有多个,XyzTests有多个。
模板方法模式(Template Method)
模板方法模式是扩展功能的最基本模式之一
它是一种 ”类的行为模式“
它是通过 ”继承“ 的方法来实现扩展
基类负责算法的轮廓和骨架
子类负责算法的具体实现
组合 vs. 继承
基于 ”继承“ 的模板方法比 ”组合“ 更容易实现
在很多情况下,可以适当使用这种模式。
模板方法的形式
抽象方法
protected abstract void step1();
强制子类实现该步骤。
具体方法
protected void doSomething() { ... }
子类不需要覆盖,但也可以覆盖之。
如想明确告诉子类 ”不要覆盖它“,最好标明:
final
钩子方法
protected void setUp() { }
空的实现(缺省适配器模式)
子类可选择性地覆盖之,以便在特定的时机做些事。
Java Servlet 中的模板方法

Java Servlet中有两个模板方法
模板方法:
service()
判断使用哪种方式处理网络请求GET, POST, PUT等。Servlet interface
也是个模板方法,因为Servlet的生命周期方法,一定是固定的。
测试 Sortable
测试 ArraySortable
测试 ListSortable
测试排序程序类图

策略模式(Strategy)
策略模式是扩展功能的另一种最基本的模式
它是一种 ”对象的行为模式“
它是通过 ”组合“ 的方法来实现扩展

什么时候使用策略模式?
系统需要在多种算法中选择一种
重构系统时
将条件语句转换成对于策略的多态性调用
策略模式的优点(对比模板方法)
将使用策略的人与策略的具体实现分离
策略对象可以自由组合
策略模式可能存在的问题:
策略模式仅仅封装了 ”算法的具体实现“,方便添加和替换算法。但它并不关心何时使用何种算法,这个必须由客户端来决定。
策略模式和模板方法的结合

参数化的单元测试
上述代码生成一个 ”测试包“

生成更复杂的 ”测试包“

组合模式(Composite)
组合模式
是一种 ”对象的结构模式“

组合模式的应用
文件系统
AWT 控件

测试排序程序的性能
冒泡排序和插入排序,谁更快?
这种测试必须重复多次(如10,000次)侧能比较准确地计算出性能。
如何让 BubbleSorterTests 和 InsertionSorterTests 重复运行多次,而不需要修改他们的代码?
如何计算时间?
运用 JUnit 扩展包中的辅助类:
junit.extensions.TestSetup
junit.extensions.RepeatedSetup
性能测试程序
性能测试核心源码
装饰器模式(Decorator)

装饰器模式
是一种 ”对象的结构模式“
装饰器模式的作用
在不改变对客户端的接口的前提下(对客户端透明)
扩展现有对象的功能
思考 PerformanceTests 的客户端是指谁?
装饰器模式也被笼统地称为 ”包装器“(Wrapper)
适配器也被称作 ”包装器“,区别在于适配器是转换成另一个接口,而装饰器是保持接口不变。
包装器形成一条 ”链“。

装饰器模式 ”包装器“例子(Wrapper)
明月装饰了梦装饰了你
梦装饰了明月装饰了你
装饰器模式的优缺点
装饰器和模板方法、策略模式的比较
装饰器保持对象的功能不变,扩展其外围的功能。
模板方法和策略模式则保持算法的框架不变,而扩展其内部的实现。
装饰器和继承的比较
都可以用来扩展对象的功能
但装饰器是动态的,继承是静态的
装饰器可以任意组合
☞ 但这也使装饰器更复杂,有可能会组合出荒谬的结果
装饰器模式的应用
Java Servlet 中的应用
HttpServletRequest
/HttpServletRequestWrapper
HttpServletResponse
/HttpServletResponseWrapper
同步化装饰器
Collections.synchronizedList(list)
取代原先的
Vector
、Hashtable
等同步类。
Java I/O 类库简介
核心 - 流, 即数据的有序排列,将数据从源送达目的地。
流的种类
☞ InputStream
、OutputStream
- 代表 byte
流 (八位字节流)
☞ Reader
、Writer
- 代表 char
流(Unicode
字符流)
流的对称性
☞ 输入 - 输出对称
☞ Byte
- Char
对称
☞ 因此我们只要学习任意一种流,就可以基本了解其它所有的流。
依赖注入 DI 与控制反转 IOC

DI、 IOC 的应用例子
DI、 IOC 的核心源码
Spring 中的单例模式
单例怎么获取: beanMap.get(ref)
Spring MVC 模式

SQL in Hadoop Eco-system
Hive
Impala
Presto
Phoenix
Shark
Hive Architecture

开源地址:
An analytical SQL engine for MapReduce

Exists Case Study
SQL 转换为语法树

复杂的问题通过装饰者模式变得简答

transformer 把Oracle SQL转换为join
generator 把Oracle SQL转换为Hive SQL
开闭原则
难的问题解决了,后人就比较容易理解了。
比如爱因斯坦的相对论,现在高中生都在学习。
牛顿力学,现在初中生都在学习。
复杂的问题理解了,就算前任理解了,后人理解还是比较难理解复杂的问题。
注意:以上信息如有侵权,请联系作者删除,谢谢。
版权声明: 本文为 InfoQ 作者【John(易筋)】的原创文章。
原文链接:【http://xie.infoq.cn/article/71a7607ad92507cba04b82718】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论 (1 条评论)