# 概述
# 产生背景
- 最初出现在建筑领域设计中
- 1995年,GoF出版《设计模式:可复用面向对象软件的基础》,收录23个设计模式,是设计模式领域里程碑事件
- 直到今天,狭义设计模式,还是指的该教程的23种经典设计模式。
# 概念与意义
- 概念
- 一套被反复使用、多数人知晓的,代码设计经验的总结
- 是解决特定问题的一系列套路,具有一定的普遍性
- 意义
- 提高思维能力,编程能力,设计能力
- 程序设计更加标准化,代码更加工程化
- 代码可重用性高、可读性强、可靠性高、灵活性好
# 基本要素
- 模式名称
- 问题:解释设计问题和问题存在的前因后果,以及必须满足的一系列先决条件;
- 解决方案: 提供设计问题的抽象描述,以及具有一般意义的元素组合。
- 效果:模式的优缺点
# GOF的23种设计模式
# 分类
- 根据目的划分为:
- 创建型模式
- 结构型模式
- 行为型模式
- 根据作用范围划分为:
- 类模式
- 对象模式
范围\目的 | 创建型 | 结构型 | 行为型 |
---|---|---|---|
类模式 | 工厂方法 | (类)适配器 | 模板方法 解释器 |
对象模式 | 单例 原型 抽象工厂 建造者 | 代理 (对象)适配器 桥接 装饰 外观 享元 组合 | 策略 命令 职责链 状态 观察者 中介者 迭代器 访问者 备忘录 |
# 正确使用设计模式
- 技术永远为业务服务,技术只是满足业务需求的一个工具
- 许多设计模式的功能类似,界限不是特别清楚;
- 设计模式,只是实现七大设计原则的具体方式,套用太多设计模式,只会陷入模式套路陷阱,最后代码写的凌乱不堪;
# 创建型模式
# 模式概要
- 主要关注点是怎样创建对象?
- 主要特点是将对象的创建与使用分离
# 单例模式
某个类只能生成一个实例,提供一个全局访问点供外部获取该实例
# 在开源框架中的应用
- jdk的体现
public class Runtime {
private static Runtime currentRuntime = new Runtime();
public static Runtime getRuntime() {
return currentRuntime;
}
/*xxx: 禁用构造函数*/
private Runtime() {}
}
- spring中的体现(容器级别的单例)
public interface BeanFactory {
/*xxx: 根据指定的名称,从bean容器获取bean*/
Object getBean(String name) throws BeansException;
}
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
/*xxx: 单例对象的缓存*/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
Object sharedInstance = getSingleton(beanName);
}
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
}
}
spring的单例bean实例的创建,使通过代码自己控制的,单例bean保存在一个ConcurrentHashMap
中,不是典型的单例模式的实现。
此处的spring的单例,是在IOC容器
中,实际开发中,还涉及到线程间单例以及分布式多进程间单例。线程间单例,可以通过ThreadLocal
实现,进程间单例要借助分布式锁以及单例实例的序列号与反序列化.
# 需要注意的问题
- 是否懒加载
- 是否线程安全问题;
# 原型模式
将一个对象作为原型,通过对其进行复制,而克隆出多个和原型类似的新实例。
# 在开源框架中的应用
- spring中的体现
/*xxx: package org.springframework.beans; */
public abstract class BeanUtils {
public static void copyProperties(Object source, Object target) throws BeansException {
copyProperties(source, target, null, (String[]) null);
}
/*xxx: 深拷贝*/
private static void copyProperties(Object source, Object target, @Nullable Class<?> editable,
@Nullable String... ignoreProperties) throws BeansException {
/*xxx: 获取属性信息*/
PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
/*xxx: 遍历属性信息 */
for (PropertyDescriptor targetPd : targetPds) {
/*xxx: 获取目标对象的setter方法 */
Method writeMethod = targetPd.getWriteMethod();
/*xxx: 从源对象中,获取 setter方法,对应的属性*/
PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
/*xxx: 获取源对象中的read方法*/
Method readMethod = sourcePd.getReadMethod();
/*xxx: 从源对象读取出属性 */
Object value = readMethod.invoke(source);
/*xxx: 写入目标对象*/
writeMethod.invoke(target, value);
}
}
}
- commons-beanutils中的体现
//package org.apache.commons.beanutils;
public class BeanUtilsBean {
public Object cloneBean(Object bean)
throws IllegalAccessException, InstantiationException,
InvocationTargetException, NoSuchMethodException {
Object newBean = null;
/*xxx: 实例化新实例*/
newBean = bean.getClass().newInstance();
/*xxx: 拷贝属性到新实例中*/
getPropertyUtils().copyProperties(newBean, bean);
return (newBean);
}
}
public class PropertyUtilsBean {
public void copyProperties(Object dest, Object orig)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
if (orig instanceof DynaBean) {
/*xxx: 省略抽象...*/
}else if (orig instanceof Map) {
/*xxx: 省略抽象...*/
} else {
/*xxx: 获取源对象的所有属性*/
PropertyDescriptor[] origDescriptors =
getPropertyDescriptors(orig);
/*xxx: 对属性进行遍历*/
for (int i = 0; i < origDescriptors.length; i++) {
String name = origDescriptors[i].getName();
if (isReadable(orig, name) && isWriteable(dest, name)) {
/*xxx: 获取源属性的值*/
Object value = getSimpleProperty(orig, name);
/*xxx: 设置目标属性的值*/
setSimpleProperty(dest, name, value);
}
}
}
}
}
# 工厂模式
定义一个用于生产产品的接口,由子类决定生产什么产品.
# 在开源框架中的应用
- spring中的体现
/*xxx: 顶级接口,通知器链工厂*/
public interface AdvisorChainFactory {
/*xxx: 获取拦截器以及动态拦截通知*/
List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass);
}
/*xxx: 顶级接口,bean容器*/
public interface BeanFactory {
/*xxx: 根据指定的名称,从bean容器获取bean*/
Object getBean(String name) throws BeansException;
}
/*xxx: 代理工厂*/
public class ProxyFactory extends ProxyCreatorSupport {
/*xxx: 获取代理对象,具有多个重载方法,最终都是通过这个流程完成*/
public Object getProxy() {
return createAopProxy().getProxy();
}
}
/*xxx: 顶级接口,aop动态代理工厂*/
public interface AopProxyFactory {
/*xxx: 根据被代理对象的配置信息,创建aop动态代理*/
AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException;
}
mybatis
中的体现
public interface SqlSessionFactory {
SqlSession openSession(boolean autoCommit);
}
/*xxx: 该工厂负责 创建代理对象*/
/*xxx: 映射代理工厂*/
public class MapperProxyFactory<T> {
/*xxx: 当前MapperProxyFactory对象,可以创建实现了mapperInterface接口的代理对象*/
private final Class<T> mapperInterface;
/*xxx: 缓存,key是 mapperInterface接口中某方法对应的Method对象,value是对应的MapperMethod对象*/
private final Map<Method, MapperMethodInvoker> methodCache = new ConcurrentHashMap<>();
protected T newInstance(MapperProxy<T> mapperProxy) {
/*xxx: 创建 实现了 mapperInterface接口的代理对象*/
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}
/*xxx: 负责创建实现了 mapperInterface 接口的代理对象的功能*/
public T newInstance(SqlSession sqlSession) {
/*xxx: 创建 MapperProxy对象,每次调用都会创建新的 MapperProxy对象*/
final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
}
# 抽象工厂模式
提供一个创建产品族的接口,每个子类生产一系列相关的产品;
# 在开源框架中的应用
jdk
中的体现
public interface Connection extends Wrapper, AutoCloseable {
//xxx: 返回普通的sql执行器
Statement createStatement() throws SQLException;
//xxx: 返回具有参数化预编译功能的sql执行器
PreparedStatement prepareStatement(String sql)
throws SQLException;
//xxx: 返回可以执行存储过程的sql执行器
CallableStatement prepareCall(String sql) throws SQLException;
}
在Java生态系统中,许多知名的开源项目和框架都使用了抽象工厂模式。这种设计模式主要用于创建一系列相关或依赖的对象,而无需指定它们的具体类。以下是几个典型的知名开源项目及其如何体现抽象工厂模式的示例:
# 1. Spring Framework
Spring 是 Java 开发中最流行的框架之一,广泛用于企业级应用开发。
# 抽象工厂模式的体现:
BeanFactory 和 ApplicationContext: Spring 的核心容器(如
BeanFactory
和ApplicationContext
)可以看作是抽象工厂模式的一种实现。它们负责创建和管理 Bean 对象(即应用程序中的对象),而具体的 Bean 类型由配置决定。多数据源支持: 在多数据源场景下,Spring 使用抽象工厂模式来创建不同类型的
DataSource
对象(如 MySQL、PostgreSQL 等)。通过配置不同的工厂类(如DataSourceBuilder
),Spring 可以动态生成相应的数据源对象。
# 示例代码片段:
// 抽象工厂接口
public interface DataSourceFactory {
DataSource createDataSource();
}
// 具体工厂:MySQL 数据源工厂
public class MySQLDataSourceFactory implements DataSourceFactory {
@Override
public DataSource createDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
};
// 客户端代码
DataSourceFactory factory = new MySQLDataSourceFactory();
DataSource dataSource = factory.createDataSource();
# 2. Hibernate ORM
Hibernate 是一个强大的 ORM 框架,用于将 Java 对象映射到数据库表。
# 抽象工厂模式的体现:
SessionFactory: Hibernate 中的
SessionFactory
是一个抽象工厂,用于创建Session
对象(与数据库交互的核心接口)。具体实现根据配置文件(如 XML 或注解)动态生成对应的Session
实例。Dialect 工厂: Hibernate 支持多种数据库(如 MySQL、Oracle、PostgreSQL),它通过抽象工厂模式为每种数据库提供对应的 SQL 方言(
Dialect
)。例如,MySQLDialect
和PostgreSQLDialect
是具体产品,而DialectFactory
是抽象工厂。
# 示例代码片段:
// 抽象工厂接口
public interface DialectFactory {
Dialect createDialect();
}
// 具体工厂:MySQL 方言工厂
public class MySQLDialectFactory implements DialectFactory {
@Override
public Dialect createDialect() {
return new MySQLDialect();
}
}
# 3. Apache Commons Pool
Apache Commons Pool 是一个通用的对象池库,用于管理昂贵资源(如数据库连接、线程等)的复用。
# 抽象工厂模式的体现:
- PooledObjectFactory:
PooledObjectFactory
是一个抽象工厂接口,用于创建、销毁和验证池中的对象。具体实现(如BasePooledObjectFactory
)定义了如何创建和管理具体的对象实例。
# 示例代码片段:
// 抽象工厂接口
public interface PooledObjectFactory<T> {
PooledObject<T> makeObject() throws Exception;
void destroyObject(PooledObject<T> p) throws Exception;
boolean validateObject(PooledObject<T> p);
}
// 具体工厂:数据库连接工厂
public class ConnectionFactory implements PooledObjectFactory<Connection> {
@Override
public PooledObject<Connection> makeObject() throws Exception {
return new DefaultPooledObject<>(DriverManager.getConnection("jdbc:mysql://localhost:3306/test"));
}
@Override
public void destroyObject(PooledObject<Connection> p) throws Exception {
p.getObject().close();
}
@Override
public boolean validateObject(PooledObject<Connection> p) {
return !p.getObject().isClosed();
}
}
# 4. Log4j
Log4j 是一个流行的日志记录框架,用于在应用程序中记录日志信息。
# 抽象工厂模式的体现:
- LoggerFactory:
Log4j 中的
LoggerFactory
是一个抽象工厂,用于创建不同类型的Logger
对象(如控制台日志、文件日志等)。具体实现根据配置文件动态选择合适的日志记录器。
# 示例代码片段:
// 抽象工厂接口
public interface LoggerFactory {
Logger createLogger();
}
// 具体工厂:文件日志工厂
public class FileLoggerFactory implements LoggerFactory {
@Override
public Logger createLogger() {
return new FileLogger();
}
}
# 建造者模式
将一个复杂对象分解成多个相对简单的部分,然后根据不同需要,分别创建它们,最后构建成该复杂对象.
# 在开源框架中的应用
- spring中的体现
public final class BeanDefinitionBuilder {
public BeanDefinitionBuilder addPropertyValue(String name, @Nullable Object value) {
this.beanDefinition.getPropertyValues().add(name, value);
return this;
}
public BeanDefinitionBuilder addAutowiredProperty(String name) {
this.beanDefinition.getPropertyValues().add(name, AutowiredPropertyMarker.INSTANCE);
return this;
}
/*xxx: 省略其它抽象...*/
/*xxx: 从构造器中,获取实际的bean信息*/
public AbstractBeanDefinition getBeanDefinition() {
this.beanDefinition.validate();
return this.beanDefinition;
}
}
- springSecurity中的体现
public interface SecurityBuilder<O> {
/*xxx: 过滤链的构造*/
O build() throws Exception;
}
public abstract class AbstractSecurityBuilder<O> implements SecurityBuilder<O> {
private AtomicBoolean building = new AtomicBoolean();
/*xxx: 过滤链*/
private O object;
/*xxx: 执行构建*/
protected abstract O doBuild() throws Exception;
}
public abstract class AbstractConfiguredSecurityBuilder<O, B extends SecurityBuilder<O>>
extends AbstractSecurityBuilder<O> {
//xxx: 既用了构造模式,也用了泛型
public <C extends SecurityConfigurer<O, B>> C apply(C configurer) throws Exception {
add(configurer);
return configurer;
}
}
public final class HttpSecurity extends
AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>
implements SecurityBuilder<DefaultSecurityFilterChain>,
HttpSecurityBuilder<HttpSecurity> {
public OAuth2LoginConfigurer<HttpSecurity> oauth2Login() throws Exception {
return getOrApply(new OAuth2LoginConfigurer<>());
}
public FormLoginConfigurer<HttpSecurity> formLogin() throws Exception {
return getOrApply(new FormLoginConfigurer<>());
}
public OpenIDLoginConfigurer<HttpSecurity> openidLogin() throws Exception {
return getOrApply(new OpenIDLoginConfigurer<>());
}
/*xxx: 省略其它抽象...*/
}
jdk
中的体现
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
/*xxx: 省略其它抽象...*/
@Override
public String toString() {
return new String(value, 0, count);
}
}
# 结构型模式
# 模式概要
- 主要关注点是如何将类或对象按某种布局组成更大的结构
- 分为类结构型模式、对象结构型模式,类结构模式通过继承机制来组织接口和类,对象结构模式通过组合或聚合来组织对象
- 组合关系或者聚合关系,比继承关系耦合度更低,满足合成复用原则,所以对象结构模型比类结构模型具有更大的灵活性.
- 除了适配器模式分为类结构模式和对象结构模式外,其它都是属于对象型模式
# 代理模式
对某对象提供一种代理,以控制对该对象的访问。即消费者通过代理,间接地访问对象,从而限制、增强、或修改该对象的一些特性.
# 开源框架中的体现
- springWeb中的体现
/*xxx: springSecurity与web集成时候的入口类*/
public class DelegatingFilterProxy extends GenericFilterBean {
@Nullable
/*xxx: 代理对象*/
private volatile Filter delegate;
public DelegatingFilterProxy(Filter delegate) {
this.delegate = delegate;
}
@Override
/*xxx: 作为一个过滤器 在 容器的 applicationFilterChain 进行过滤*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
/*xxx: 懒实例化过滤器代理对象 */
Filter delegateToUse = this.delegate;
/*省略部分抽象...*/
/*xxx: 执行过滤器代理*/
invokeDelegate(delegateToUse, request, response, filterChain);
}
protected void invokeDelegate(
Filter delegate, ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
/*xxx: 通过过滤器代理进行过滤操作*/
delegate.doFilter(request, response, filterChain);
}
}
- jdk中的动态代理
/*xxx: 通过这一个接口,将所有的方法进行聚合*/
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
/*xxx: 该方法需要使用强转,转为实际的接口 */
public class Proxy implements java.io.Serializable {
protected InvocationHandler h;
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
/*xxx: 省略抽象*/
}
}
# 适配器模式
将一个类的接口转换成消费者希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类能一起工作。
# 开源框架中的体现
- springSecurity中的体现
public abstract class WebSecurityConfigurerAdapter implements
WebSecurityConfigurer<WebSecurity> {
/*xxx: 正常情况下,该接口是用于 单个配置器的初始化工作,此处用于新增过滤链了*/
public void init(final WebSecurity web) throws Exception {
final HttpSecurity http = getHttp();
/*xxx: 省略其它抽象...*/
web.addSecurityFilterChainBuilder(http);
}
@Override
/*xxx: 正常情况下,该接口由于编织单条过滤链,此处不做处理*/
public void configure(WebSecurity web) throws Exception {
}
}
- springWebMVC中的体现
public abstract class AbstractHandlerMethodAdapter extends WebContentGenerator implements HandlerAdapter, Ordered {
@Override
@Nullable
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return handleInternal(request, response, (HandlerMethod) handler);
}
@Nullable
protected abstract ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception;
}
# 桥接模式
将抽象与实现分离,使它们可以独立变化.通过利用组合关系,降低了抽象和实现这两个可变维度的耦合度。
- 可以理解为 通过变量传递,实现 接口定义与实际实现的分离
# 开源框架中的体现
- spring中的体现
public interface CacheManager {
@Nullable
Cache getCache(String name);
}
public interface FlashMapManager {
FlashMap retrieveAndUpdate(HttpServletRequest request, HttpServletResponse response);
void saveOutputFlashMap(FlashMap flashMap, HttpServletRequest request, HttpServletResponse response);
}
- jdbc中的体现
public class DriverManager {
@CallerSensitive
public static Connection getConnection(String url,
java.util.Properties info) throws SQLException {
return (getConnection(url, info, Reflection.getCallerClass()));
}
private static Connection getConnection(
String url, java.util.Properties info, Class<?> caller) throws SQLException {
/*xxx: 省略其它抽象...*/
for(DriverInfo aDriver : registeredDrivers) {
Connection con = aDriver.driver.connect(url, info);
/*xxx: 省略其它抽象...*/
return (con);
}
}
}
- springCloud中的体现
public class EnvironmentManager implements ApplicationEventPublisherAware {
private ConfigurableEnvironment environment;
public Object getProperty(String name) {
return this.environment.getProperty(name);
}
}
# 装饰模式
动态地给对象增加一些职责,即增加其额外的功能;
# 开源框架中的体现
- mybatis中的体现
public interface Cache {
void putObject(Object key, Object value);
Object getObject(Object key);
}
public class LoggingCache implements Cache {
private final Cache delegate;
private final Log log;
@Override
public void putObject(Object key, Object object) {
delegate.putObject(key, object);
}
@Override
public Object getObject(Object key) {
final Object value = delegate.getObject(key);
/*xxx: 省略其它抽象...*/
if (log.isDebugEnabled()) {
log.debug("Cache Hit Ratio [" + getId() + "]: " + getHitRatio());
}
return value;
}
}
public class LruCache implements Cache {
private final Cache delegate;
private Map<Object, Object> keyMap;
@Override
public Object getObject(Object key) {
keyMap.get(key);
return delegate.getObject(key);
}
}
# 外观模式
为多个复杂的子系统提供一个一致的接口,使这些子系统更加容易被访问
# 开源框架中的体现
- tomcat中的体现
public class ApplicationContextFacade implements ServletContext {
private final ApplicationContext context;
/*xxx: 记录方法,与参数对象信息 */
private final Map<String,Class<?>[]> classCache;
private void initClassCache(){
Class<?>[] clazz = new Class[]{String.class};
classCache.put("getContext", clazz);
classCache.put("getMimeType", clazz);
classCache.put("getResourcePaths", clazz);
classCache.put("getResource", clazz);
classCache.put("getResourceAsStream", clazz);
classCache.put("getRequestDispatcher", clazz);
classCache.put("getNamedDispatcher", clazz);
classCache.put("getServlet", clazz);
classCache.put("setInitParameter", new Class[]{String.class, String.class});
classCache.put("createServlet", new Class[]{Class.class});
classCache.put("addServlet", new Class[]{String.class, String.class});
classCache.put("createFilter", new Class[]{Class.class});
classCache.put("addFilter", new Class[]{String.class, String.class});
classCache.put("createListener", new Class[]{Class.class});
classCache.put("addListener", clazz);
classCache.put("getFilterRegistration", clazz);
classCache.put("getServletRegistration", clazz);
classCache.put("getInitParameter", clazz);
classCache.put("setAttribute", new Class[]{String.class, Object.class});
classCache.put("removeAttribute", clazz);
classCache.put("getRealPath", clazz);
classCache.put("getAttribute", clazz);
classCache.put("log", clazz);
classCache.put("setSessionTrackingModes", new Class[]{Set.class} );
classCache.put("addJspFile", new Class[]{String.class, String.class});
classCache.put("declareRoles", new Class[]{String[].class});
classCache.put("setSessionTimeout", new Class[]{int.class});
classCache.put("setRequestCharacterEncoding", new Class[]{String.class});
classCache.put("setResponseCharacterEncoding", new Class[]{String.class});
}
@Override
public ServletContext getContext(String uripath) {
theContext = (ServletContext)
doPrivileged("getContext", new Object[]{uripath});
}
private Object doPrivileged(final String methodName, final Object[] params) {
return invokeMethod(context, methodName, params);
}
private Object invokeMethod(ApplicationContext appContext,
final String methodName,
Object[] params)
throws Throwable{
method = appContext.getClass()
.getMethod(methodName, classCache.get(methodName));
objectCache.put(methodName, method);
return executeMethod(method,appContext,params);
}
private Object executeMethod(final Method method,
final ApplicationContext context,
final Object[] params)
throws PrivilegedActionException,
IllegalAccessException,
InvocationTargetException {
return method.invoke(context, params);
}
}
# 享元模式
运用共享技术,来有效地支持大量细粒度对象的复用。
# 开源框架中的体现
- jdk中的体现
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 Integer cache[];
/*xxx: 省略其它抽象...*/
}
}
- springSeuciry中的体现
# 组合模式
将对象组合成树状层次结构,使用户对单个对象和组合对象具有一致的访问性.
# 开源框架中的体现
- mybatis中的体现
public interface SqlNode {
boolean apply(DynamicContext context);
}
public class TrimSqlNode implements SqlNode {
/*xxx: 调用子节点的 apply方法进行解析*/
boolean result = contents.apply(filteredDynamicContext);
/*xxx: filteredDynamicContext.applyAll 处理前缀 和 后缀*/
filteredDynamicContext.applyAll();
return result;
}
public class WhereSqlNode extends TrimSqlNode {
private static List<String> prefixList = Arrays.asList("AND ","OR ","AND\n", "OR\n", "AND\r", "OR\r", "AND\t", "OR\t");
public WhereSqlNode(Configuration configuration, SqlNode contents) {
super(configuration, contents, "WHERE", prefixList, null, null);
}
}
- springSecurity中的体现
public final class WebSecurity extends
AbstractConfiguredSecurityBuilder<Filter, WebSecurity> implements
SecurityBuilder<Filter>, ApplicationContextAware {
@Override
protected Filter performBuild() throws Exception {
int chainSize = ignoredRequests.size() + securityFilterChainBuilders.size();
List<SecurityFilterChain> securityFilterChains = new ArrayList<>(
chainSize);
/*xxx: 省略其它抽象...*/
FilterChainProxy filterChainProxy = new FilterChainProxy(securityFilterChains);
Filter result = filterChainProxy;
return result;
}
}
# 行为型模式
# 模式概要
- 主要关注点是描述程序在运行时,复杂的流程控制,即描述多个类或对象之间怎样相互协作,共同完成单个对象无法完成的任务。涉及算法与对象间职责的分配。
- 分为类行为模式和对象行为模式,类行为模式,通过继承机制在类间分派行为,对象行为模式,通过组合或聚合在对象间分配行为。
# 模板方法模式
定义一个操作的算法骨架,将算法的一些步骤延迟到子类中,使得子类在可以不改变该算法结构的情况下,重定义该算法的某些特定步骤。
# 开源框架中的体现
- spring中的体现
- springWebMVC中的体现
public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware {
public final void init() throws ServletException {
initServletBean();
}
protected void initServletBean() throws ServletException {
}
}
public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware {
@Override
protected final void initServletBean() throws ServletException {
this.webApplicationContext = initWebApplicationContext();
initFrameworkServlet();
}
public void onApplicationEvent(ContextRefreshedEvent event) {
this.refreshEventReceived = true;
synchronized (this.onRefreshMonitor) {
onRefresh(event.getApplicationContext());
}
}
protected void onRefresh(ApplicationContext context) {
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*xxx: 实际处理请求入口*/
doService(request, response);
}
protected abstract void doService(HttpServletRequest request, HttpServletResponse response)
throws Exception;
}
public class DispatcherServlet extends FrameworkServlet {
@Override
/*xxx: 该方法 是 DispatcherServlet 的入口方法*/
protected void onRefresh(ApplicationContext context) {
/*xxx: 初始化9个组件*/
initStrategies(context);
}
protected void initStrategies(ApplicationContext context) {
/*xxx: 1.MultipartResolver组件*/
initMultipartResolver(context);
/*xxx: 2.localeResolver组件*/
initLocaleResolver(context);
/*xxx: 3.themeResolver组件*/
initThemeResolver(context);
/*xxx: 4.handlerMapping组件*/
initHandlerMappings(context);
/*xxx: 5.handlerAdapter组件*/
initHandlerAdapters(context);
/*xxx: 6.handlerExceptionResolver组件*/
initHandlerExceptionResolvers(context);
/*xxx: 7.requestToViewNameTranslator组件*/
initRequestToViewNameTranslator(context);
/*xxx: 8.viewResolver组件*/
initViewResolvers(context);
/*xxx: 9.flashMapManager组件*/
initFlashMapManager(context);
}
@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
/*xxx: 进行分发处理*/
doDispatch(request, response);
}
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
/*xxx: 根据 request 找到 handler*/
mappedHandler = getHandler(processedRequest);
/*xxx: 根据handler找到 handlerAdapter*/
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
/*xxx: 处理上面处理之后的结果 (包括 处理异常,渲染页面,发出完成通知触发 Interceptor 的 afterCompletion)*/
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
/*xxx: 处理分发结果 */
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
@Nullable Exception exception) throws Exception {
/*xxx: 渲染页面,具体在 render方法中执行*/
render(mv, request, response);
}
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
view = resolveViewName(viewName, mv.getModelInternal(), locale, request);
view.render(mv.getModelInternal(), request, response);
}
protected View resolveViewName(String viewName, @Nullable Map<String, Object> model,
Locale locale, HttpServletRequest request) throws Exception {
/*xxx: 省略其它抽象...*/
View view = viewResolver.resolveViewName(viewName, locale);
}
}
# 策略模式
定义一系列算法,并将算法封装起来,使它们可以相互替换,且算法的改变不会影响使用算法的客户。
# 开源框架中的体现
- spring中的体现
public interface InstantiationStrategy {
Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner)
throws BeansException;
/*xxx: 省略其他抽象...*/
}
public class SimpleInstantiationStrategy implements InstantiationStrategy {
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
/*xxx: 最终,通过 BeanUtils进行实例化,通过构造方法*/
return BeanUtils.instantiateClass(constructorToUse);
}
}
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
/*xxx: 创建bean实例的策略*/
private InstantiationStrategy instantiationStrategy;
public AbstractAutowireCapableBeanFactory() {
/*xxx: 省略其他抽象...*/
if (IN_NATIVE_IMAGE) {
this.instantiationStrategy = new SimpleInstantiationStrategy();
}
else {
this.instantiationStrategy = new CglibSubclassingInstantiationStrategy();
}
}
public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) {
this.instantiationStrategy = instantiationStrategy;
}
protected InstantiationStrategy getInstantiationStrategy() {
return this.instantiationStrategy;
}
@Override
public Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException {
bean = getInstantiationStrategy().instantiate(bd, null, this);
/*xxx: 省略其它抽象...*/
populateBean(beanClass.getName(), bd, new BeanWrapperImpl(bean));
return bean;
}
}
- springAop中的体现
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
/*xxx: 创建AOP动态代理*/
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!IN_NATIVE_IMAGE &&
(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
/*xxx: 如果被代理对象是 接口,则动态代理采用 jdk的动态代理进行编织*/
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
/*xxx: 如果被代理对象是 实例类,则动态代理采用 cglib的动态代理进行编织*/
return new ObjenesisCglibAopProxy(config);
}else{
/*xxx: 当前环境是否是原生环境,原生环境,则只能使用 jdk动态代理*/
return new JdkDynamicAopProxy(config);
}
}
}
# 命令模式
将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分隔开。
# 开源框架中的体现
- tomcat中的体现
/*xxx: 适配器,用于找到请求对应的 组件*/
public class CoyoteAdapter implements Adapter {
@Override
/*xxx: 可以看成tomcat的核心流程的处理起点 多线程环境*/
public void service(org.apache.coyote.Request req, org.apache.coyote.Response res)
throws Exception {
request = connector.createRequest();
request.setCoyoteRequest(req);
response = connector.createResponse();
response.setCoyoteResponse(res);
request.setResponse(response);
response.setRequest(request);
/*xxx: 3.得到当前引擎的第一个Valve并执行(invoke),以完成客户端请求处理*/
/*xxx: 由于pipieline和 valve为职责链模式,因此执行第一个Valve即保证了整个Valve链的执行*/
/*xxx: 省略其它抽象...*/
connector.getService().getContainer().getPipeline().getFirst().invoke(
request, response);
}
}
# 职责链模式
把请求链中的一个对象,传到下一个对象,直到请求被响应为止。通过这种方式去除对象之间的耦合。
# 开源框架中的体现
- tomcat中的体现
/*xxx: 应用过滤器,由tomcat 实现的servlet 过滤器规范 */
public final class ApplicationFilterChain implements FilterChain {
@Override
/*xxx: 进行过滤动作 */
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
internalDoFilter(request,response);
}
/*xxx: 实际过滤动作 */
private void internalDoFilter(ServletRequest request,
ServletResponse response)
throws IOException, ServletException {
/*xxx: 过滤器 往下迭代, 注意此处迭代的 是原生的过滤器。 */
if (pos < n) {
/*xxx: 从原生过滤器配置信息 数组中进行迭代 */
ApplicationFilterConfig filterConfig = filters[pos++];
/*xxx: 根据过滤器配置信息,获取实际的过滤器实例 */
Filter filter = filterConfig.getFilter();
/*xxx: 根据获取到的过滤器 执行 过滤,并将当前的 过滤器实例作为参数传入 */
filter.doFilter(request, response, this);
}
}
}
- springMVC中的体现
public class DispatcherServlet extends FrameworkServlet {
/*xxx: 需要注意,HandlerMapping 具有优先级关系*/
/*xxx: 在前的优先*/
@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
for (HandlerMapping mapping : this.handlerMappings) {
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
/*xxx: handlerAdapter也具有优先级关系*/
/*xxx: 在前的优先 */
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
for (HandlerAdapter adapter : this.handlerAdapters) {
if (adapter.supports(handler)) {
return adapter;
}
}
}
/*xxx: 省略其它抽象...*/
}
}
# 状态模式
允许一个对象,在其内部状态发生改变时,改变其行为能力。
# 开源框架中的体现
- spring中的体现
public final class ParseState {
private final ArrayDeque<Entry> state;
public ParseState() {
this.state = new ArrayDeque<>();
}
public void pop() {
this.state.pop();
}
public void push(Entry entry) {
this.state.push(entry);
}
}
class ConfigBeanDefinitionParser implements BeanDefinitionParser {
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
/*xxx: 省略其它抽象...*/
List<Element> childElts = DomUtils.getChildElements(element);
for (Element elt: childElts) {
String localName = parserContext.getDelegate().getLocalName(elt);
if (POINTCUT.equals(localName)) {
parsePointcut(elt, parserContext);
}
else if (ADVISOR.equals(localName)) {
parseAdvisor(elt, parserContext);
}
else if (ASPECT.equals(localName)) {
parseAspect(elt, parserContext);
}
}
}
private AbstractBeanDefinition parsePointcut(Element pointcutElement, ParserContext parserContext) {
this.parseState.push(new PointcutEntry(id));
pointcutDefinition = createPointcutDefinition(expression);
pointcutDefinition.setSource(parserContext.extractSource(pointcutElement));
String pointcutBeanName = id;
parserContext.getRegistry().registerBeanDefinition(pointcutBeanName, pointcutDefinition);
/*xxx: 省略其他抽象...*/
this.parseState.pop();
}
}
- springBoot中的体现
class SpringApplicationRunListeners {
void contextLoaded(ConfigurableApplicationContext context) {
doWithListeners("spring.boot.application.context-loaded", (listener) -> listener.contextLoaded(context));
}
void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
doWithListeners("spring.boot.application.environment-prepared",
(listener) -> listener.environmentPrepared(bootstrapContext, environment));
}
/*xxx: 省略其它抽象...*/
private void doWithListeners(String stepName, Consumer<SpringApplicationRunListener> listenerAction,
Consumer<StartupStep> stepAction) {
StartupStep step = this.applicationStartup.start(stepName);
this.listeners.forEach(listenerAction);
if (stepAction != null) {
stepAction.accept(step);
}
step.end();
}
}
# 观察者模式
多个对象间,存在一对多关系,当一个对象发生改变时,把这种改变通知给其它多个对象,从而影响其它对象的行为。
# 开源框架中的体现
- spring中的体现
/*xxx: 应用事件发布器 */
public interface ApplicationEventPublisher {
/*xxx: 发布事件(对象类型)*/
void publishEvent(Object event);
}
/*xxx: 抽象应用上下文*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
@Nullable
/*xxx: 当前上下文使用的 事件发布器*/
private ApplicationEventMulticaster applicationEventMulticaster;
@Override
public void publishEvent(Object event) {
publishEvent(event, null);
}
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
/*xxx: 省略其它抽象...*/
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
}
public interface ApplicationEventMulticaster {
/*xxx: 新增应用监听器,交由抽象实现*/
void addApplicationListener(ApplicationListener<?> listener);
/*xxx: 上下文发布事件,实际调用的是该方法,交由具体类实现*/
void multicastEvent(ApplicationEvent event);
/*xxx: 省略其它抽象...*/
}
public abstract class AbstractApplicationEventMulticaster
implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {
private final DefaultListenerRetriever defaultRetriever = new DefaultListenerRetriever();
@Override
public void addApplicationListener(ApplicationListener<?> listener) {
this.defaultRetriever.applicationListeners.add(listener);
}
protected Collection<ApplicationListener<?>> getApplicationListeners(
ApplicationEvent event, ResolvableType eventType) {
/*xxx: 省略其它抽象...*/
newRetriever = new CachedListenerRetriever();
/*xxx: 从所有的监听器中,遴选出 符合条件的 监听器群组*/
return retrieveApplicationListeners(eventType, sourceType, newRetriever);
}
private Collection<ApplicationListener<?>> retrieveApplicationListeners(
ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable CachedListenerRetriever retriever) {
List<ApplicationListener<?>> allListeners = new ArrayList<>();
synchronized (this.defaultRetriever) {
listeners = new LinkedHashSet<>(this.defaultRetriever.applicationListeners);
listenerBeans = new LinkedHashSet<>(this.defaultRetriever.applicationListenerBeans);
}
for (ApplicationListener<?> listener : listeners) {
if (supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
filteredListeners.add(listener);
}
allListeners.add(listener);
}
}
/*xxx: 省略其它抽象...*/
/*xxx: 将所有的监听器进行排序*/
AnnotationAwareOrderComparator.sort(allListeners);
return allListeners;
}
private class DefaultListenerRetriever {
public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
}
}
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
@Override
public void multicastEvent(ApplicationEvent event) {
multicastEvent(event, resolveDefaultEventType(event));
}
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
/*xxx: 从这里可以看出,对监听器的执行是通过遍历执行的*/
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
/*xxx: 异步执行*/
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}/*xxx: 同步执行*/
else {
invokeListener(listener, event);
}
}
}
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
/*xxx: 省略其它抽象...*/
listener.onApplicationEvent(event);
}
}
# 中介者模式
定义一个,中介对象来简化原有对象之间交互关系,降低系统中对象间的耦合性,使原有对象之间不必相互了解。
# 开源框架中的体现
- jdk中的体现
public class Timer {
private final TaskQueue queue = new TaskQueue();
private final TimerThread thread = new TimerThread(queue);
public Timer(String name) {
thread.setName(name);
thread.start();
}
public void schedule(TimerTask task, long delay) {
sched(task, System.currentTimeMillis()+delay, 0);
}
public void schedule(TimerTask task, Date time) {
sched(task, time.getTime(), 0);
}
/*xxx: 省略其它抽象...*/
private void sched(TimerTask task, long time, long period) {
synchronized(queue) {
/*xxx: 省略其它抽象...*/
queue.add(task);
if (queue.getMin() == task)
queue.notify();
}
}
}
class TaskQueue {
private TimerTask[] queue = new TimerTask[128];
TimerTask getMin() {
return queue[1];
}
}
class TimerThread extends Thread {
private TaskQueue queue;
public void run() {
mainLoop();
}
private void mainLoop() {
while (true) {
synchronized(queue) {
while (queue.isEmpty() && newTasksMayBeScheduled)
queue.wait();
task = queue.getMin();
synchronized(task.lock) {
currentTime = System.currentTimeMillis();
executionTime = task.nextExecutionTime;
taskFired = (executionTime<=currentTime);
if (!taskFired)
queue.wait(executionTime - currentTime);
}
if (taskFired)
task.run();
}
}
}
}
# 迭代器模式
提供一种方法来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。
# 开源框架中的体现
- jdk中的体现
public interface Iterator<E> {
boolean hasNext();
E next();
/*xxx: 省略其它抽象...*/
}
# 访问者模式
- 在不改变集合元素的前提下,为一个集合中的每个元素,提供多种访问方式,即每个元素有多个访问者对象访问。
- 曾经看过一个说法,说访问者模式是最难理解的一种模式。 始终耿耿于怀。 时隔多年,试图剖析了这个心魔。 绝大多数谈设计的时候,都是从抽象行为来谈,也就是接口为中心来谈。而访问者则是以对象为中心来谈。 简言之,实体已定,但实体属性支持动态改变。
- 访问者模式,其行为是固化的,不明白当时为什么有人说访问者模式最难理解,导致自己总是如鲠在喉。
# 开源框架中的体现
- spring中的体现
public class BeanDefinitionVisitor {
@Nullable
private StringValueResolver valueResolver;
public BeanDefinitionVisitor(StringValueResolver valueResolver) {
this.valueResolver = valueResolver;
}
protected void visitScope(BeanDefinition beanDefinition) {
String scope = beanDefinition.getScope();
if (scope != null) {
String resolvedScope = resolveStringValue(scope);
if (!scope.equals(resolvedScope)) {
beanDefinition.setScope(resolvedScope);
}
}
}
protected void visitPropertyValues(MutablePropertyValues pvs) {
PropertyValue[] pvArray = pvs.getPropertyValues();
for (PropertyValue pv : pvArray) {
Object newVal = resolveValue(pv.getValue());
if (!ObjectUtils.nullSafeEquals(newVal, pv.getValue())) {
pvs.add(pv.getName(), newVal);
}
}
}
/*xxx: 省略其它抽象...*/
public void visitBeanDefinition(BeanDefinition beanDefinition) {
visitParentName(beanDefinition);
visitBeanClassName(beanDefinition);
visitFactoryBeanName(beanDefinition);
visitFactoryMethodName(beanDefinition);
visitScope(beanDefinition);
if (beanDefinition.hasPropertyValues()) {
visitPropertyValues(beanDefinition.getPropertyValues());
}
if (beanDefinition.hasConstructorArgumentValues()) {
ConstructorArgumentValues cas = beanDefinition.getConstructorArgumentValues();
visitIndexedArgumentValues(cas.getIndexedArgumentValues());
visitGenericArgumentValues(cas.getGenericArgumentValues());
}
}
}
public abstract class PlaceholderConfigurerSupport extends PropertyResourceConfigurer
implements BeanNameAware, BeanFactoryAware {
protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
StringValueResolver valueResolver) {
BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(valueResolver);
String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames();
for (String curName : beanNames) {
visitor.visitBeanDefinition(bd);
}
}
}
- jdk中的体现
public final class Files {
public static Path walkFileTree(Path start,
Set<FileVisitOption> options,
int maxDepth,
FileVisitor<? super Path> visitor)
throws IOException
{
FileTreeWalker walker = new FileTreeWalker(options, maxDepth);
FileTreeWalker.Event ev = walker.walk(start);
switch (ev.type()) {
case ENTRY :
result = visitor.visitFile(ev.file(), ev.attributes());
break;
case START_DIRECTORY :
result = visitor.preVisitDirectory(ev.file(), ev.attributes());
break;
case END_DIRECTORY :
result = visitor.postVisitDirectory(ev.file(), ev.ioeException());
break;
default :
throw new AssertionError("Should not get here");
}
}
}
public interface FileVisitor<T> {
FileVisitResult visitFile(T file, BasicFileAttributes attrs)
throws IOException;
FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
throws IOException;
/*xxx: 省略其它抽象...*/
}
# 备忘录模式
在不破坏封装性的前提下,获取并保存一个对象的内部状态,以便以后回复它。
# 开源框架中的体现
- springWebFlow中的体现
public interface StateManageableMessageContext extends MessageContext {
Serializable createMessagesMemento();
void restoreMessages(Serializable messagesMemento);
}
# 解释器模式
提供如何定义语言的文法,以及对语言句子的解释方法,即解释器。
# 开源框架中的体现
- jdk中的体现
public final class Pattern
implements java.io.Serializable
{
public static Pattern compile(String regex) {
return new Pattern(regex, 0);
}
public static boolean matches(String regex, CharSequence input) {
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(input);
return m.matches();
}
/*xxx: 省略其它抽象...*/
}
- spring中的体现
public interface ExpressionParser {
Expression parseExpression(String expressionString) throws ParseException;
/*xxx: 省略其它抽象...*/
}