写点什么

第三周 学习总结

用户头像
Yangjing
关注
发布于: 2020 年 10 月 01 日
第三周 学习总结

这周主要内容为设计模式,系统设计的最终目标是:高内聚、低耦合。上周说到的系统设计的原则有:开闭原则、依赖倒置原则、里氏替换原则、单一职责原则、接口隔离原则,这些原则都是抽象的,而设计模式是笔设计原则更具体的方法,设计模式是一种可重复使用的解决方案。每一种模式都描述了一种问题的通用解决方案,这些问题不停地在我们环境中出现。

概念

一个模式的四个不分:

  • 模式的名称 - 有助于在沟通中表达我们的设计

  • 解决的问题 - 描述了设计模式出现的上下文(环境),什么时候需要设计模式

  • 解决方案 - 设计模式的组成元素(类和对象),它们的关系、职责以及合作。但这种方案是抽象的,不代表具体的实现。

  • 结论 - 方案的利和弊。对系统弹性、扩展性和可移植性的影响。

从功能上分:

创建模式 - 对类的实例化过程的抽象

结构模式 - 将类或者对象结合在一起形成更大的结构

行为模式 - 在不同的对象之间划分责任和算法的抽象化

从方式分:

类模式 - 以继承的方式实现模式,静态的。

对象模式 - 以组合的方式实现模式,动态的。

简单工厂

如何创建一个对象,如果直接 new 一个对象,应用程序不符合开闭原则的。

  1. 简单工厂模式

public class SorterFactory {
public static <T> Sorter<T> getSorter() {
return new BubbleSorter();
}
}
public class Client {
public static void main(String[] args) {
Sorter<Integer> sorter = SorterFactory.getSorter();
}
}

对应用程序 ```Client ``` 符合开闭原则,排序算法改动,不用改变 Client 类代码,但是对 SorterFactory 不符合开闭原则。

  1. 改进了的工厂模式

public class SorterFactory {
private final static Properties IMPLS = loadImpls();
@SuppressWarnings("unchecked")
public static <T> Sorter<T> getSorter() {
String implClassName = IMPLS.getProperty("sorter");
try {
Class implClass = Class.forName(implClassName);
return (Sorter<T>) implClass.newInstance();
} catch (Exception e) {
throw new IllegalArgumentException(
"Illegal class name: "+ implClassName, e
);
}
}
private static Properties loadImpls() {
Properties defaultImpls = new Properties();
Properties impls = new Properties(defaultImpls);
defaultImpls.setProperty("sorter", "demo.sort.impl.BubbleSorter");
try {
impls.load(SorterFactory.class.getResourceAsStream("sort.properties"));
} catch (IOException e) {
throw new RuntimeException(e);
}
return impls;
}
}

创建 sort.properties 文件,配置

sorter=demo.sort.impl.BubbleSorter



改进了的简单工厂方法,通过配置文件解决简单工厂的开闭原则问题。



单例模式

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

  1. 只有一个实例,减少实例频繁创建和销毁带来的资源消耗。 性能需求

  2. 现实情况中,确实只有一个实例。如 打印机对象。 功能需求



  • 饿汉模式,实例对象在需要之前已经创建出来

public class Singleton1 {
// 私有的方法,保证单一性
private Singleton1() {
}
// 私有的静态变量,比类的构造函数提前创建
private static Singleton1 instance = new Singleton1();
public static Singleton1 getInstance() {
return instance;
}
}
  • 懒汉模式,在实例对象需要时,才会进行创建

public class Singleton {
private Singleton() {}
private static volatile Singleton instance = null;
// 加锁,保证同一个时候,只有一个线程创建实例
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}

推荐使用饿汉形式的单例模式

尽量将单例设计成无状态的对象(只提供服务,不保存状态)

适配器模式

当需要某个类的某些功能,但是类提供的方法不是定义的方法,无法直接调用。比如在策略模式的使用中

适配器实现接口方法,方法实际调用的事实现类的接口方法。

  • 类适配器调用适配器的父类去实现接口的方法

  • 对象适配器是调用组合对象的接口去实现接口方法

类适配器

public interface NewSortable<T> {
int size();
T getElement(int i);
void setElement(int i, T o);
}
/**
* @description 对象适配器,实际执行接口方法的为对象中组合对象的实例
* @version v1.0
*/
public class ListSortable<T> implements NewSortable<T> {
private final List<T> list;
public ListSortable(List<T> list) {
this.list = list;
}
@Override
public int size() {
return list.size();
}
@Override
public T getElement(int i) {
return list.get(i);
}
@Override
public void setElement(int i, T o) {
list.set(i, o);
}
}

类通过继承来执行需要适配的方法。



对象适配器

public interface NewSortable<T> {
int size();
T getElement(int i);
void setElement(int i, T o);
}
public class SortableList<T> extends ArrayList<T> implements NewSortable<T> {
@Override
public T getElement(int i) {
return get(i);
}
@Override
public void setElement(int i, T o) {
set(i, o);
}
}





适配器的使用

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

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

JUnit 中使用的设计模式

模版方法模式

父类定义复杂算法的轮廓和骨架,子类中实现算法和骨架

抽象方法

protected abstract void step1();

强制子类实现该步骤

具体方法

protected void doSomething() {...}

子类不需要覆盖,也可以覆盖

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

钩子方法

protected void step2() {...}

空的实现,缺省适配器模式

子类可选择性地覆盖之,以便在特定的时机做些其他事

策略模式

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

  • 是一种“对象的行为”



应用程序针对策略接口进行编程,具体的实现类去实现接口,在程序运行期通过注入具体策略实现类实现策略方法,但在开发期应用程序是针对接口进行编程。

  • 通过组合来进行扩展



什么时候使用策略模式

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

  • 重构时,将条件语句转换成对于策略的多态调用



优点:

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

  • 策略对象可以自由组合

可能存在的问题:

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



大多情况下策略和模板模式结合。

组合模式

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

树结构的处理



测试排序程序的性能

装饰器模式

对象的结构模式。要装饰的类与要实现的是同一个接口,扩展现有接口的功能

有时候也被称为“包装器”,但是包装过后,接口不变。

它和适配器的区别在于:适配器是转换为另一个接口,而装饰器是保持接口不变。

包装器形成一条“链”

实例:

Collections.synchronizedList(list)

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

Java I/O 类

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

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

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

  • 流的对称性

  1. 输入、输出对称

  2. Byte、Char 对称

  3. 只要学习任意一种流,就可以基本了解其他所有的流

Spring 中的设计模式

设计模式很多,只要能解决重复出现的问题

  • IoC 模式。通常对象间依赖,A对象依赖B对象,A 对象需要自己去构建 B 对象,而依赖注入是说A对象不需要自己去构建B对象,而是由外部去创建,并注入这个依赖,这就叫依赖注入。

  • Spring 中的单例模式,通过容器控制。

  • Spring MVC 模式。

发布于: 2020 年 10 月 01 日阅读数: 49
用户头像

Yangjing

关注

还未添加个人签名 2017.11.09 加入

还未添加个人简介

评论

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