Week3 学习总结 (模式与重构)

发布于: 2020 年 06 月 21 日
Week3学习总结(模式与重构)

面向对象的设计模式

设计模式的定义

什么是设计模式?

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

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

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

  • 模式的名称

  • 待解问题

  • (抽象)解决方案

  • 结论(利弊)

排序问题——如何创建对象?

利用简单工厂模式

public class SorterFactory {
public static <T> Sorter<T> getSorter() {
return new BubbleSorter<T>();
}
}
public class Client {
public static void main(String[] args) {
Integer[] array = { 5, 4, 9, 7, 6, 3, 8, 1, 0, 2 };
Sorter<Integer> sorter = SorterFactory.getSorter();
Sortable<Integer> sortable = SortableFactory.getSortable(array);
Comparator<Integer> comparator = ComparatorFactory.getComparator();
sorter.sort(sortable, comparator);
……
}
}

简单工厂优点:

  • 使Client不再依赖Sorter的具体实现(如BubbleSorter)

  • 对Client实现OCP - 增加Sorter时不影响Client

简单工厂缺点:

  • 对Factory未实现OCP - 增加Sorter需要修改Factory

改进一

class SorterFactory_2 {
@SuppressWarnings("unchecked")
public static <T> Sorter<T> getSorter(String implClass) {
try {
Class impl = Class.forName(implClass);
return (Sorter<T>) impl.newInstance();
} catch (Exception e) {
throw new IllegalArgumentException("Illegal class name: " + implClass, e);
}
}
}
Sorter<Integer> sorter = SorterFactory_2.getSorter("demo.sort.impl.BubbleSorter");

改进一存在问题

  • 增加Sorter实现时,不需要修改Factory了,但仍需修改Client

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

  • Client和Factory均类型不安全

  • Client仍然“知道”Sorter的实现是什么

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

改进二

class SorterFactory_3 {
private final static Properties IMPLS = loadImpls();
private static Properties loadImpls() {
Properties defaultImpls = new Properties();
Properties impls = new Properties(defaultImpls);
defaultImpls.setProperty("sorter","demo.sort.impl.BubbleSorter");
try {
impls.load(SorterFactory_3.class.getResourceAsStream("sort.properties"));
} catch (IOException e) {
throw new RuntimeException(e);
}
return impls;
}
@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);
}
}
}
//创建sort.properties 文件
• sorter=demo.sort.impl.BubbleSorter

改进二优点

  • 对于Client和Factory均满足

  • 满足OCP方法

  • 抽象

  • 动态编程(即将编译时类型检查转变成运行时检查)

改进二缺点

  • 缺少编译时类型安全

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

Singleton单例模式

为什么要用?

  • 减少实例频繁创建和销毁带来的资源消耗;

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

// 方法一
public class Singleton1 {
private Singleton1 () {}
private static Singleton1 instance = new Singleton1();
public static Singleton1 getInstance() {
return instance;
}
}
// 方法二
public class Singleton2 {
private Singleton2 () {}
private static Singleton2 instance = null;
public static synchronized Singleton2 getInstance() {
if (instance == null)
instance = new Singleton2();
return instance;
}
}

适配器模式

类的适配器

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

对象的适配器

public class ListSortable<T> implements Sortable<T> {
private final List<T> list;
public ListSortable(List<T> list) {
this.list = list;
}
public int size() {
return list.size();
}
public T get(int i) {
return list.get(i);
}
public void set(int i, T o) {
list.set(i, o);
}
}

适配器的作用

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

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

适配器的应用

  • JDBC Driver

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

  • 例如,将Oracle适配到JDBC中

  • JDBC-ODBC Bridge

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

JUint中的设计模式

策略模式:

  • 应用程序——》策略接口(策略抽象)——》策略实现

模板方法模式

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

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

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

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

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

模板方法的形式

  • 抽象方法

  • protected abstract void step1();

  • 强制子类实现该步骤

  • 具体方法

  • protected void doSomething() { … }

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

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

  • 钩子方法

  • protected void setUp() { }

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

  • 子类可选择性地覆盖

Java Servlet 中的模板方法

何时使用模板方法?

  • 重构系统时

  • 将一个大方法打破,变成多个可扩展的步骤

  • 将if/else或switch语句改成多态性

  • 模板方法可能产生的问题

  • 将抽象算法和具体步骤耦合,不能独立演化

  • 造成类的数量很多、类的层次很深,例如:Spring的测试工具类

策略模式

也是扩展功能的最基本模式之一

  • “对象的行为模式”

它通过“组合”的方法实现扩展

什么时候使用?

  • 重构系统时

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

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

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

  • 策略对象可以自由组合

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

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

策略模式和模板方法的结合

组合模式

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

装饰器模式

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

作用

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

  • 扩展现有对象的功能

发布于: 2020 年 06 月 21 日 阅读数: 9
用户头像

星河寒水

关注

还未添加个人签名 2018.09.17 加入

还未添加个人简介

评论

发布
暂无评论
Week3学习总结(模式与重构)