写点什么

第三周学习总结

用户头像
晴空万里
关注
发布于: 2020 年 11 月 08 日

周标题:代码重构

  1. 设计模式:使用设计模式优化排序工具包设计

  2. 设计模式:Singleton 单例模式

  3. jUnit 中的设计模式

  4. Spring 中的设计模式

  5. 设计模式案例:Intel 大数据 SQL 引擎 &Panthera 设计模式


这周的标题虽然是代码重构,但是老师没有怎么提代码重构这个说法,不知道为什么,一上来讲的是设计模式的作用。


设计模式的作用:把高屋建瓴的 OOD 原则变成通用的解决方案。


定义:(2 个定义,4 个部分)

  1. 每一种模式都描述了一种问题的通用解决方案。这种问题在我们环境中,不停地出现。

  2. 设计模式是一种可重复使用的解决方案。


一个设计模式的四个部分:

  1. 模式的名称:由少量的字组成的名称,有助于我们表达我的设计。(见名知意

  2. 待解问题:描述了何时需要运用这种模式,以及运用模式的环境。(识别场景,它认识我,我不认识它)

  3. 解决方案:描述了组成设计的元素(类和对象)、它们的关系、职责以及合作。但这种解决方案是抽象的,它不代表具体的实现。(怎么搞它)

  4. 结论:运用这种方式所带来的利弊。主要是指它对系统的弹性、扩展性和可移植性的影响。(各有利弊)


设计模式的分类:2 大类,5 小类

从功能分:

  • 创建模式(Creational Patterns)

  • 对类的实例化过程的抽象

  • 结构模式(Structural Patterns)

  • 将类或对象结合在一起形成更强大的结构

  • 行为模式(Behavioral Patterns)

  • 对在不同的对象之间划分责任和算法的抽象化

从方式分

  • 类模式

  • 以继承的方式实现模式,静态的

  • 对象模式

  • 以组合的方式实现模式,动态的


具体例子:排序问题?


从排序问题引出简单工厂模式,不能依赖于实现编程,依赖于接口编程。


简单工厂的优缺点:(基于例子而言)

优点:

  • 客户端不在依赖具体的接口实现

  • 客户端满足了 OCP-增加新的实现不影响客户端

缺点:

  • 工厂本身未实现 OCP-增加实现类需要修改工厂


简单工厂改进一:

反射的方式创建排序接口实现类

  • 增加接口实现类,不需要修改工厂

  • 但是还是需要修改客户端

其它问题:

  • 丧失了编译时的类型安全

  • 客户端和工厂类均类型不安全

  • 客户端仍然“知道”接口的实现是什么

  • 限制了接口实现只能通过“默认构造函数”创建


简单工厂改进二:

增加配置文件

  • 客户端和工厂均满足 OCP

  • 满足 OCP 抽象、动态编程(即将编译时类型检查转变成运行时检查)

缺点:

  • 缺少编译时类型安全

  • 限制了接口的实现只能通过“默认构造函数”创建

但是这种方法其实相当重要

  • 简单工厂非常重要,是许多模式的基础

  • 该机制解决了简单工厂模式最致命的问题


Singleton 单例模式


为什么使用?

Singleton 模式保证产生单一实例,就是说一个类只产生一个实例。使用 Singleton 有两个原因:

  • 是因为只有一个实例,可以减少实例频繁创建和销毁带来的资源消耗

  • 是当多个用户使用这个实例的时候,便于进行统一控制(比如打印机对象)


前者是性能需求,后者是功能需求


备注:此处手写单例模式,作业。


关于单例模式:

  1. 构造函数一定要私有,保证类的实例只能通过唯一方法获取到,例如 getInstance

  2. 使用饿汉式的时候,getInstance 方法一定要 synchronized 修饰,否则线程挣抢,产生多实例

  3. 尽量使用饱汉式

  4. 单例的成员变量在多线程环境下是重用的,尽量将单例设计为无状态对象(只提供服务,不保存状态)


适配器模式(Adapter)

  • 类的适配器

  • 对象的适配器

适配器的作用

系统需要使用现有的类,而这个类的接口与我们所需要的不同

  • 例如:我们需要对 List 进行排序,但是我们需要一个 Sortable 接口,原有的 List 接口不能满足要求


适配器的应用

JDBC Driver

  • 是对具体数据库的适配器

  • 例如将 Oracle 适配到 JDBC 中

JDBC-ODBC Driver

  • 是将 Windows ODBC 适配到 JDBC 接口中


jUnit 中的设计模式


模板方法模式(Template Method)

模板方法模式是扩展功能的最基本模式之一

  • 它是一种“类的行为模式”

它是通过“继承”的方法来实现扩展

  • 基类负责算法的轮廓和骨架

  • 子类负责算法的具体实现


组合 VS 继承

  • 基于“继承”的模板方法与“组合”更容易实现

  • 在很多情况下,可以适当的使用这种模式


模板方法的形式

抽象方法:

  • protected abstract void step1();

  • 强制子类实现该步骤

具体方法:

  • protected void doSomething(){}

  • 子类不需要覆盖,但也可以覆盖之

  • 如想明确告诉子类“不要覆盖它”,最好标明:final

钩子方法

  • protected void setUp(){}

  • 空的实现(缺省适配器模式)

  • 子类可以选择性的覆盖它,以便在特定的时机做些事情


Java Servlet 中的模板方法


策略模式(Strategy)

策略模式是扩展功能的另一种最基本的模式

  • 它是一种“对象行为模式”

它是通过“组合”的方式来实现扩展


什么时候使用策略模式?

系统需要在多种算法中选择一种

重构系统时

  • 将条件语句转换成对于策略的多态性调用

策略模式的优点(对比模板方法)

  • 将使用策略的人与策略的具体实现分离

  • 策略对象可以自由组合

策略模式可能存在的问题:

  • 策略模式仅仅封装了“算法的具体实现”,方便添加和替换算法。但它并不关心何时使用何种算法,这个必须由客户端来决定。


组合模式(Composite)

  • 组合模式

  • 是一种“对象的结构模式”


装饰器模式(Decorator)

  • 是一种“对象的结构模式”

作用

  • 在不改变对客户端接口的前提下(对客户端透明)

  • 扩展现有对象的功能

装饰器模式也被笼统的称为“包装器”(Wrapper)

  • 适配器也被称作“包装器”,区别在于适配器是转换成另一个接口,而装饰器是保持接口不变

  • 包装器形成一条链


装饰器的优缺点


装饰器和模板方法、策略模式的比较

  • 装饰器保持对象的功能不变、扩展其外围的功能

  • 模板方法和策略模式则保持算法的框架不变,而扩展其内部实现


装饰器和继承的比较

  • 都可以用来扩展对象的功能

  • 但装饰器是动态的,继承是静态的

  • 装饰器可以任意组合

  • 但这也使装饰器更复杂,有可能出现荒谬的结果


装饰器的应用

Java Servlet 中的应用

  • HttpServletRequest/HttpServletRequestWraper

  • HttpServletResponse/HttpServletResponseWrapper

同步化装饰器

  • Collections.synchronizedList(list)

  • 取代原先的 Vector、Hashtable 等同步类

Java I/O 类库简介

  • 核心 - 流,即数据的有序排列,将数据从源送达到目的地

  • 流的种类

  • InputStream、OutputStream-代表 byte 流(八位字节流)

  • Reader、Writer-代表字符流(Unicode 字符流)

  • 流的对称性

  • 输入-输出对称

  • byte-char 对称

Spring 中的设计模式

依赖注入 DI 与控制反转 IoC

Spring 中的单例模式

SpringMVC 模式


总结的还是很草率,看着 PDF 抄写一遍都记不住,更何况融会贯通,灵活使用了。

还需努力。


用户头像

晴空万里

关注

还未添加个人签名 2018.07.18 加入

还未添加个人简介

评论

发布
暂无评论
第三周学习总结