一:概述
设计模式是软件开发中解决特定问题的优秀实践方案。作为Java开发者,我们每天都在使用的JDK中其实大量运用了各种设计模式。理解这些模式在JDK中的实现,不仅能帮助我们更好地使用JDK,也能提升我们的设计能力。本文将深入探讨JDK中常见的设计模式实现。
二:具体说明
一、创建型模式
1. 单例模式(Singleton)
JDK中最典型的单例模式实现是Runtime
类:
public class Runtime {private static Runtime currentRuntime = new Runtime();public static Runtime getRuntime() {return currentRuntime;}private Runtime() {}// 其他方法...
}
这个实现展示了经典的单例模式特点:
- 私有构造方法防止外部实例化
- 静态变量持有唯一实例
- 静态方法提供全局访问点
2. 工厂模式(Factory)
java.util.Collections
类中的静态方法提供了许多工厂方法:
List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());
Set<String> unmodifiableSet = Collections.unmodifiableSet(new HashSet<>());
`这些方法隐藏了具体实现类的细节,提供了创建特定功能集合的统一接口。
3. 建造者模式(Builder)
java.lang.StringBuilder
和java.lang.StringBuffer
是建造者模式的典型应用:
StringBuilder builder = new StringBuilder();
String result = builder.append("Hello").append(" ").append("World").toString();
虽然它们主要用于字符串拼接,但体现了建造者模式的核心思想:分步构建复杂对象。
二、结构型模式
1. 适配器模式(Adapter)
java.util.Arrays#asList()
方法将数组适配为List:
List<String> list = Arrays.asList("a", "b", "c");
这里Arrays.asList()
充当了适配器,将数组接口适配为List接口。
2. 装饰器模式(Decorator)
Java I/O流大量使用了装饰器模式:
InputStream is = new FileInputStream("test.txt");
InputStream bufferedIs = new BufferedInputStream(is);
InputStream gzipIs = new GZIPInputStream(bufferedIs);
每个装饰类都扩展了基础流的功能,而不改变其接口,这是装饰器模式的典型特征。
3. 代理模式(Proxy)
java.lang.reflect.Proxy
提供了动态代理的实现:
InvocationHandler handler = new MyInvocationHandler();
MyInterface proxy = (MyInterface) Proxy.newProxyInstance(MyInterface.class.getClassLoader(),new Class[] { MyInterface.class },handler);
动态代理在AOP、RPC等场景中广泛应用。
三、行为型模式
1. 迭代器模式(Iterator)
Java集合框架中的Iterator
是迭代器模式的典范:
List<String> list = Arrays.asList("a", "b", "c");
Iterator<String> it = list.iterator();
while(it.hasNext()) {System.out.println(it.next());
}
迭代器将集合的遍历操作与集合实现分离。
2. 观察者模式(Observer)
早期JDK中的java.util.Observable
和java.util.Observer
(Java 9已废弃)实现了观察者模式:
Observable observable = new Observable();
observable.addObserver((o, arg) -> System.out.println("Changed: " + arg));
observable.notifyObservers("Hello");
现代Java更常用PropertyChangeListener
或其他事件机制。
3. 策略模式(Strategy)
java.util.Comparator
是策略模式的典型例子:
Collections.sort(list, new Comparator<String>() {public int compare(String a, String b) {return b.compareTo(a);}
});
通过不同的Comparator实现,可以灵活改变排序策略。
4. 模板方法模式(Template Method)
java.io.InputStream
中的read()
方法:
public abstract class InputStream {public abstract int read() throws IOException;public int read(byte b[]) throws IOException {// 模板方法实现...}
}
子类只需实现抽象read()
方法,非抽象方法提供了模板实现。
四、并发模式
1. 不可变对象模式(Immutable Object)
java.lang.String
是最著名的不可变对象:
String s = "hello";
String s2 = s.toUpperCase(); // 返回新对象,不改变原对象
不可变对象在多线程环境下具有天然的线程安全性。
2. 线程局部存储模式(Thread Local Storage)
java.lang.ThreadLocal
实现了线程局部变量:
ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(() -> 0);
每个线程访问自己的变量副本,避免了线程安全问题。
五、函数式编程模式
Java 8引入的Lambda和Stream API带来了新的模式:
1. 函数接口(Functional Interface)
java.util.function
包中的各种函数式接口:
Function<String, Integer> lengthFunc = String::length;
Predicate<String> isEmpty = String::isEmpty;
这些接口支持了Java的函数式编程能力。
2. 流式处理(Fluent Interface)
Stream API的链式调用:
List<String> result = list.stream().filter(s -> s.startsWith("A")).map(String::toUpperCase).collect(Collectors.toList());
这种流畅的接口设计提高了代码的可读性。
总结
JDK中设计模式的应用无处不在,理解这些模式在核心库中的实现,可以帮助我们:
- 更深入地理解JDK的设计思想
- 在自己的代码中更好地应用这些模式
- 编写出更优雅、更易维护的代码
设计模式不是银弹,但它们是经过验证的解决方案。JDK中的这些实现展示了如何在实际项目中恰当地应用设计模式,值得我们反复学习和思考。
作为Java开发者,我们不仅应该了解这些模式,更应该理解它们解决的问题和适用场景,这样才能在适当的时候选择合适的设计方案。