创建模式
1.抽象工厂
- javax.xml.parsers.DocumentBuilderFactory抽象类
public static DocumentBuilderFactory newInstance()方法
类功能:使得应用程序可以通过 XML 文件,获得一个能生成 DOM 对象的解析器
方法功能:获取一个 DocumentBuilderFactory 的新实例。这一静态方法会创建一个新的工厂实例
public abstract class DocumentBuilderFactory {
public static DocumentBuilderFactory newInstance() {
// 创建一个抽象工厂
return FactoryFinder.find(
/* The default property name according to the JAXP spec */
DocumentBuilderFactory.class, // "javax.xml.parsers.DocumentBuilderFactory"
/* The fallback implementation class name */
"com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
}
public static DocumentBuilderFactory newInstance(String factoryClassName, ClassLoader classLoader){
// 创建一个抽象工厂
//do not fallback if given classloader can't find the class, throw exception
return FactoryFinder.newInstance(DocumentBuilderFactory.class, factoryClassName, classLoader, false);
}
}
2.建造者模式
- java.lang.StringBuilder,这是一个final类
public StringBuilder append(String str)方法,这一方法是对父类的覆写
类功能:用于一个不可更改的字符序列
方法功能:根据现有字符序列和追加字符,通过系统拷贝方法 System.arraycopy 生成一个新的字符序列
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence {
// StringBuffer的append实现和StringBuilder一摸一样,只是在此方法上增加了synchronized并清空字符串缓存
@Override
public StringBuilder append(String str) {
// 调用父类的append方法
super.append(str);
return this;
}
}
abstract class AbstractStringBuilder implements Appendable, CharSequence {
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
// 调用String的getChars方法
str.getChars(0, len, value, count);
count += len;
return this;
}
}
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
if (srcBegin < 0) {
throw new StringIndexOutOfBoundsException(srcBegin);
}
if (srcEnd > value.length) {
throw new StringIndexOutOfBoundsException(srcEnd);
}
if (srcBegin > srcEnd) {
throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
}
// 最终实现 是个native方法了
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}
}
3.工厂模式
- java.text.NumberFormat抽象类
public final static NumberFormat getInstance()方法
类功能:用于数字格式的抽象基类
方法功能:返回一个“对当前默认场景下的一个通用数字格式”的 NumberFormat。显然属于工厂模式的使用
public abstract class NumberFormat extends Format {
public final static NumberFormat getInstance() {
return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
}
private static NumberFormat getInstance(Locale desiredLocale, int choice) {
LocaleProviderAdapter adapter;
adapter = LocaleProviderAdapter.getAdapter(NumberFormatProvider.class,
desiredLocale);
NumberFormat numberFormat = getInstance(adapter, desiredLocale, choice);
if (numberFormat == null) {
numberFormat = getInstance(LocaleProviderAdapter.forJRE(),
desiredLocale, choice);
}
return numberFormat;
}
private static NumberFormat getInstance(LocaleProviderAdapter adapter, Locale locale, int choice) {
NumberFormatProvider provider = adapter.getNumberFormatProvider();
NumberFormat numberFormat = null;
switch (choice) {
case NUMBERSTYLE:
numberFormat = provider.getNumberInstance(locale);
break;
case PERCENTSTYLE:
numberFormat = provider.getPercentInstance(locale);
break;
case CURRENCYSTYLE:
numberFormat = provider.getCurrencyInstance(locale);
break;
case INTEGERSTYLE:
numberFormat = provider.getIntegerInstance(locale);
break;
}
return numberFormat;
}
}
4.原型模式
- java.lang.Object
protected native Object clone() 方法
类功能:所有类的父类
方法功能:根据现有实例,返回一个浅拷贝对象
public class Object {
// 注意下这里是浅拷贝
// 浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象
protected native Object clone() throws CloneNotSupportedException;
}
5.单例模式
- java.lang.RunTime类
public static Runtime getRuntime()
类功能:每一个运行的 java 应用都会有一个唯一的 RunTime 类的实例,这个实例使得应用程序在运行期间能够受到运行环境的影响
方法功能:返回一个和当前 java 应用关联的 RunTime 对象
public class Runtime {
// 典型的饿汉式 因为每次启动虚拟机都对应一个RunTime,所以使用饿汉式比较简单?
private static Runtime currentRuntime = new Runtime();
public static Runtime getRuntime() {
return currentRuntime;
}
private Runtime() {}
}
结构模式
6.适配器模式
- java.util.Arrays
public static List asList(T… a)方法
类功能:此类包含了大量对数组操作的方法
方法功能:将一个引用类型的数组转为一个 List。从而可以使用 List 类的操作来操作数组对象,但是有一点要注意:就是不能使用 add(),remove() 操作,因为返回的 list 底层是基于数组的,数组结构是不能更改的。list 类就是这里的适配器,通过这个适配器,对数组的直接操作变为间接操作
public class Arrays {
// 其实不是asList是适配器模式 而是静态内部类ArrayList才是适配器
// 它继承了AbstractList 但没有全部实现其方法
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable {
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
@Override
public int size() {
return a.length;
}
@Override
public Object[] toArray() {
return a.clone();
}
@Override
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
int size = size();
if (a.length < size)
return Arrays.copyOf(this.a, size, (Class<? extends T[]>) a.getClass());
System.arraycopy(this.a, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
@Override
public E get(int index) {
return a[index];
}
@Override
public E set(int index, E element) {
E oldValue = a[index];
a[index] = element;
return oldValue;
}
@Override
public int indexOf(Object o) {
E[] a = this.a;
if (o == null) {
for (int i = 0; i < a.length; i++)
if (a[i] == null)
return i;
} else {
for (int i = 0; i < a.length; i++)
if (o.equals(a[i]))
return i;
}
return -1;
}
@Override
public boolean contains(Object o) {
return indexOf(o) != -1;
}
@Override
public Spliterator<E> spliterator() {
return Spliterators.spliterator(a, Spliterator.ORDERED);
}
@Override
public void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action);
for (E e : a) {
action.accept(e);
}
}
@Override
public void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
E[] a = this.a;
for (int i = 0; i < a.length; i++) {
a[i] = operator.apply(a[i]);
}
}
@Override
public void sort(Comparator<? super E> c) {
Arrays.sort(a, c);
}
}
}
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
}
7.桥接模式
在 Java SE 中,桥接模式通常用于实现 JDBC 驱动程序。JDBC(Java Database Connectivity)提供了一种方法来连接不同类型的数据库,例如 MySQL、Oracle、SQL Server 等。使用桥接模式可以将 JDBC 驱动程序分为两个部分:JDBC API 和 JDBC 驱动程序实现。JDBC API 定义了连接数据库的标准接口,而 JDBC 驱动程序实现则是实现这些接口的具体代码。JDBC API 和 JDBC 驱动程序实现之间的桥接就是通过桥接模式来实现的。
8.组合模式
- java.awt.Container类
public Component add(Component comp)方法
类功能:一个通用的AWT(Abstract Window Toolkit)容器,能够用于存储其它 AWT 组件
方法功能:添加一个AWT组件到容器中
9.装饰器模式
- Reader抽象类和Writer抽象类有相同的构造器函数
构造器函数
类功能:Reader 抽象类用于读一个字符集流;Writer 抽象类用于写一个字符集流
方法功能:就是构造函数的功能
// 这里举个别的例子吧
public interface Cache {
void put(Object key, @Nullable Object value);
}
public class TransactionAwareCacheDecorator implements Cache {
private final Cache targetCache;
public void put(final Object key, @Nullable final Object value) {
// 增加了事务的装饰
if (TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
public void afterCommit() {
TransactionAwareCacheDecorator.this.targetCache.put(key, value);
}
});
} else {
this.targetCache.put(key, value);
}
}
}
10.门面模式(外观模式)
- javax.faces.context.ExternalContext,内部使用了 ServletContext, HttpSession, HttpServletRequest, HttpServletResponse 等等
// 这里举个别的例子吧
// 日志框架是经典的外观模式
public interface Logger {
String ROOT_LOGGER_NAME = "ROOT";
String getName();
boolean isTraceEnabled();
void trace(String var1);
boolean isDebugEnabled();
void debug(String var1);
boolean isInfoEnabled();
void info(String var1);
boolean isWarnEnabled();
void warn(String var1);
boolean isErrorEnabled();
void error(String var1);
}
11.享元模式
- java.lang.Integer(其它基本类型包装类(除去Float,Double )也如此,还有BigDecimal)
Integer.valueOf()方法
byte,short,int,long,boolean,char 的包装型在类加载到 JVM 时,已经缓存了制定范围的对象引用,因为值的设定使用的是 static 块或者常量。其中 char的范围为:0~127;boolean 的值为 true 和 false;其它默认范围都是 -127~128。其中 in t的上限 127 可以调整,这需要调整 JVM 的参数
同时利用了享元模式的还有 String 这个类,因为生存的每个字符串都是不可变的
public final class Integer extends Number implements Comparable<Integer> {
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
// 调用缓存好的数据
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
// 缓存的数据
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
}
12.代理模式
- java.lang.reflect.Proxy类
原理:代理提供了一个static方法用于创建一个动态代理类和被代理类的实例。它是所有通过此方式创建动态代理类的父类
使用方式:
InvocationHandler handler = new MyInvocationHandler(...);
class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class);
Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class).newInstance(handler);
// 也可以更简单的写为:
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[]{Foo.class},handler);
行为模式
13.职责链模式
- java.util.logging.Logger类
public void log(LogRecord record)
类功能:为系统 or 组件记录日志消息。如何体现了职责链模式:每个记录器都跟踪“父”记录器,所谓”父”记录器,就是 Logger 命名空间中最近的现有祖先
方法功能:用于记录日志信息。这一类中所有其它的日志方法都是通过调用这一方法实现日志记录的。子类能够覆写这一方法从而获取所有的日志行为
14.命令模式
- java.lang.Runnable
所有对 Runable 接口的实现类
类功能:实现 Runable 接口的类,可以被线程执行
如果体现了命令模式:通过实现 Runable 接口的类,将请求封装为一个对象,对请求排队或记录请求日志,以及支持可撤销操作。允许接受请求的一方决定是否要否决请求,最重要一点就是:命令模式把请求一个操作的对象和怎么执行一个操作的对象解耦。这就是 Excutor 框架执行实现 Runable 接口任务类的体现
15.解释器模式
- java.text.Format
类功能:此抽象类用于格式化一些格式敏感的信息,如:日期,信息,数字等
实现方式:此类定义了一些方法,用于:将格式敏感的信息转为 String
16.迭代器模式
这个就不说了,很多集合已经使用了迭代器进行遍历
17.中介者模式
- java.util.concurrent.Executor接口
定位:行为方法类通常定义为抽象/接口类型(抽象/接口类型通常使用命令模式),此类代理/使用了这一行为实例
如何体现 :Executor 框架将工作单元和执行机制解耦和。java 多线程程序通常把应用分解为多个任务,然后 Executor 框架将这些任务映射为固定数量的线程;在底层,操作系统内核将这些线程映射到硬件 CPU 上
18.备忘录模式
- java.io.Serializable接口
接口功能:只有实现了 Serializable 接口的类才能序列化,此接口中没有任何方法,只是为类标记实现了此接口的类可以进行序列化。而如果一个类想要序列化,除了实现这个接口外,还要自己写 ReadObject(),WriteObject() 方法,用于对流的读取和输出
19.观察者模式(发布/订阅模式)
- java.util.EventListener接口
类功能:所有事件监听接口,都必须扩展此接口
20.状态模式
- javax.faces.webapp.FacesServlet
实例方法的执行依赖于实例状态
21.策略模式
- java.util.Comparator函数接口
compare()方法
比较器的使用就是:先写一个比较器,然后对 Arrays 或者 Collections 排序的时候,将写好的比较器作为参数传入排序的方法,就能实现按照比较器的规则,对 Arrays 或者 Collections 进行排序
比较器方法如何体现策略模式的:策略模式是指:一个类/接口A的行为方法的执行,是通过调用另一个不同的类/接口B而实现的。调用方式是将B作为A的传入参数。这和 Comparator 的原理完全一致
22.模版方法模式
- java.util.AbstractList
所有的非抽象方法
如何体现模版方法模式:模版方法模式定义,就是说:在一个抽象类中行为方法总是有一个默认行为,子类可以直接使用,也可以覆写。 ArrayList 继承了 AbstractList,没有覆写的方法在使用时,直接使用 Abstract 中的方法
23.访问者模式
- java.nio.file.FileVisitor接口
类功能:一个用于访问文件的接口。这一接口的实现类通过 Files.walkFileTree 方法实现对文件树中每一个文件的访问
public static Path walkFileTree(Path start,Set options,
int maxDepth,FileVisitor\< super Path> visitor) ,这一方法中回调了 visitor 的方法
方法实现上:访问者对每一个被访问者都有一个实现方法。每一个被访问者都有一个通用方法,输入参数为访问者,此方法用于调用访问者的方法
InvocationHandler handler = new MyInvocationHandler(...);
class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class);
Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class).newInstance(handler);
// 也可以更简单的写为:
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[]{Foo.class},handler);
public final class Integer extends Number implements Comparable<Integer> {
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
// 调用缓存好的数据
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
// 缓存的数据
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
}
// 这里举个别的例子吧
// 日志框架是经典的外观模式
public interface Logger {
String ROOT_LOGGER_NAME = "ROOT";
String getName();
boolean isTraceEnabled();
void trace(String var1);
boolean isDebugEnabled();
void debug(String var1);
boolean isInfoEnabled();
void info(String var1);
boolean isWarnEnabled();
void warn(String var1);
boolean isErrorEnabled();
void error(String var1);
}
// 这里举个别的例子吧
public interface Cache {
void put(Object key, @Nullable Object value);
}
public class TransactionAwareCacheDecorator implements Cache {
private final Cache targetCache;
public void put(final Object key, @Nullable final Object value) {
// 增加了事务的装饰
if (TransactionSynchronizationManager.isSynchronizationActive()) {
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
public void afterCommit() {
TransactionAwareCacheDecorator.this.targetCache.put(key, value);
}
});
} else {
this.targetCache.put(key, value);
}
}
}
public class Arrays {
// 其实不是asList是适配器模式 而是静态内部类ArrayList才是适配器
// 它继承了AbstractList 但没有全部实现其方法
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable {
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
@Override
public int size() {
return a.length;
}
@Override
public Object[] toArray() {
return a.clone();
}
@Override
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
int size = size();
if (a.length < size)
return Arrays.copyOf(this.a, size, (Class<? extends T[]>) a.getClass());
System.arraycopy(this.a, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
@Override
public E get(int index) {
return a[index];
}
@Override
public E set(int index, E element) {
E oldValue = a[index];
a[index] = element;
return oldValue;
}
@Override
public int indexOf(Object o) {
E[] a = this.a;
if (o == null) {
for (int i = 0; i < a.length; i++)
if (a[i] == null)
return i;
} else {
for (int i = 0; i < a.length; i++)
if (o.equals(a[i]))
return i;
}
return -1;
}
@Override
public boolean contains(Object o) {
return indexOf(o) != -1;
}
@Override
public Spliterator<E> spliterator() {
return Spliterators.spliterator(a, Spliterator.ORDERED);
}
@Override
public void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action);
for (E e : a) {
action.accept(e);
}
}
@Override
public void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
E[] a = this.a;
for (int i = 0; i < a.length; i++) {
a[i] = operator.apply(a[i]);
}
}
@Override
public void sort(Comparator<? super E> c) {
Arrays.sort(a, c);
}
}
}
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
}
public class Runtime {
// 典型的饿汉式 因为每次启动虚拟机都对应一个RunTime,所以使用饿汉式比较简单?
private static Runtime currentRuntime = new Runtime();
public static Runtime getRuntime() {
return currentRuntime;
}
private Runtime() {}
}
public class Object {
// 注意下这里是浅拷贝
// 浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象
protected native Object clone() throws CloneNotSupportedException;
}
public abstract class NumberFormat extends Format {
public final static NumberFormat getInstance() {
return getInstance(Locale.getDefault(Locale.Category.FORMAT), NUMBERSTYLE);
}
private static NumberFormat getInstance(Locale desiredLocale, int choice) {
LocaleProviderAdapter adapter;
adapter = LocaleProviderAdapter.getAdapter(NumberFormatProvider.class,
desiredLocale);
NumberFormat numberFormat = getInstance(adapter, desiredLocale, choice);
if (numberFormat == null) {
numberFormat = getInstance(LocaleProviderAdapter.forJRE(),
desiredLocale, choice);
}
return numberFormat;
}
private static NumberFormat getInstance(LocaleProviderAdapter adapter, Locale locale, int choice) {
NumberFormatProvider provider = adapter.getNumberFormatProvider();
NumberFormat numberFormat = null;
switch (choice) {
case NUMBERSTYLE:
numberFormat = provider.getNumberInstance(locale);
break;
case PERCENTSTYLE:
numberFormat = provider.getPercentInstance(locale);
break;
case CURRENCYSTYLE:
numberFormat = provider.getCurrencyInstance(locale);
break;
case INTEGERSTYLE:
numberFormat = provider.getIntegerInstance(locale);
break;
}
return numberFormat;
}
}
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence {
// StringBuffer的append实现和StringBuilder一摸一样,只是在此方法上增加了synchronized并清空字符串缓存
@Override
public StringBuilder append(String str) {
// 调用父类的append方法
super.append(str);
return this;
}
}
abstract class AbstractStringBuilder implements Appendable, CharSequence {
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
// 调用String的getChars方法
str.getChars(0, len, value, count);
count += len;
return this;
}
}
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
if (srcBegin < 0) {
throw new StringIndexOutOfBoundsException(srcBegin);
}
if (srcEnd > value.length) {
throw new StringIndexOutOfBoundsException(srcEnd);
}
if (srcBegin > srcEnd) {
throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
}
// 最终实现 是个native方法了
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}
}
public abstract class DocumentBuilderFactory {
public static DocumentBuilderFactory newInstance() {
// 创建一个抽象工厂
return FactoryFinder.find(
/* The default property name according to the JAXP spec */
DocumentBuilderFactory.class, // "javax.xml.parsers.DocumentBuilderFactory"
/* The fallback implementation class name */
"com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
}
public static DocumentBuilderFactory newInstance(String factoryClassName, ClassLoader classLoader){
// 创建一个抽象工厂
//do not fallback if given classloader can't find the class, throw exception
return FactoryFinder.newInstance(DocumentBuilderFactory.class, factoryClassName, classLoader, false);
}
}