总结 03- 代码重构

用户头像
梦子说
关注
发布于: 2020 年 06 月 24 日

简单工厂模式

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);
……
}
}



简单工厂的优缺点

有点:

  1. 使Client不在依赖Sorter的具体实现(如BubbleSort)

  2. 对Client实现OCP——增加Sort不影响Client

缺点:

  1. 对Factory未实现OCP——增加Sort需要修改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");

解决了如下问题

  1. 增加Sort实现时,不需要修改Factory了

其他问题

  1. 丧失了编译时的类型安全

对简单工厂的改进二

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



改进后的优缺点

优点

  • 满足OCP?

  • 对Client和Factory都满足

  • 满足OCP方法

  • 抽象

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

缺点

  • 缺少编译时类型安全检查

  • 限制了Sorter的实现只能通过默认构造函数创建,无法通过构造函数传递参数

这种做法其实相当重要

  • 简单工厂相当重要,是其他许多模式的基础

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



Singleton单例模式

为什么要使用?

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

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

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

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

单例模式优缺点

优点:

(1) 由于单例模式在内存中只有一个实例,减少内存开支,特别是一个对象需要频繁地创建销毁时,而且创建或销毁时性能又无法优化,单例模式就非常明显了

(2) 由于单例模式只生成一个实例,所以,减少系统的性能开销,当一个对象产生需要比较多的资源时,如读取配置,产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式来解决。

(3) 单例模式可以避免对资源的多重占用,例如一个写文件操作,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作

(4) 单例模式可以在系统设置全局的访问点,优化和共享资源访问,例如,可以设计一个单例类,负责所有数据表的映射处理。

缺点:

(1) 单例模式没有抽象层,扩展很困难,若要扩展,除了修改代码基本上没有第二种途径可以实现。

(2) 单例类的职责过重,在一定程度上违背了“单一职责原则”。

(3) 滥用单例将带来一些负面问题,如:为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;

又比如:在多个线程中操作单例类的成员时,但单例中并没有对该成员进行线程互斥处理。



用户头像

梦子说

关注

还未添加个人签名 2018.12.01 加入

还未添加个人简介

评论

发布
暂无评论
总结03-代码重构