什么是装饰模式(Decorator):
  装饰模式是为已有功能动态的添加更多功能的一种方式;在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象;

装饰模式由4种角色组成:
  抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加职责的对象;
  具体构件(Concrete Component)角色:定义一个将要接收附加职责的类;
  装饰(Decorator)角色:持有一个构件(Component)对象的实例,并实现一个与抽象构件接口一致的接口,从外类来扩展Component类的功能,但对于Component类来说,是无需知道Decorato的存在的;
  具体装饰(Concrete Decorator)角色:负责给构件对象添加上附加的职责;

装饰模式的优点:
  1.把类中的装饰功能从类中搬移出去,这样可以简化原有的类;
  2.有效的把类的核心职责和装饰功能分开,而且可以去除相关类中重复的装饰逻辑;
  3.装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性;
  4.通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合;

装饰模式的应用场景,以下引自百度百科:
  1. 需要扩展一个类的功能,或给一个类添加附加职责;
  2. 需要动态的给一个对象添加功能,这些功能可以再动态的撤销;
  3. 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实;
  4. 当不能采用生成子类的方法进行扩充时。
    一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。
    另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类;

模式简化
  如果只有一个Concrete Component类而没有抽象的Component接口时,可以让Decorator继承Concrete Component;
  如果只有一个Concrete Decorator类时,可以将Decorator和Concrete Decorator合并;

UML类图

根据UML生成一个简单的Demo:

interface Component{void operation();
}class ConcreateComponent implements Component{@Overridepublic void operation() {System.out.println("balabala....");}
}abstract class Decorator implements Component{private Component comp;public Decorator(Component comp){this.comp = comp;}@Overridepublic void operation() {comp.operation();}
}class ConcreateDecorator extends Decorator{public ConcreateDecorator(Component comp) {super(comp);}@Overridepublic void operation() {System.out.println("begin...");super.operation();System.out.println("end...");}
}public class TestMain {public static void main(String[] args) {Component component = new ConcreateComponent();component = new ConcreateDecorator(component);component.operation();}
}

输出的结果为:

begin...
balabala....
end...

在Mybatis的Executor也采用了装饰模式,不过在使用方法上稍微有些区别,我们先看一下Executor的实现图:

以下是我从Mybatis中分离出来的一部分代码,标红部分可以重点关注一下:

package org.apache.ibatis.executor;import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.transaction.Transaction;import java.sql.SQLException;
import java.util.List;public interface Executor {ResultHandler NO_RESULT_HANDLER = null;<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException;void commit(boolean required) throws SQLException;void rollback(boolean required) throws SQLException;CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql);Transaction getTransaction();void setExecutorWrapper(Executor var1);
}

package org.apache.ibatis.executor;import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.jdbc.ConnectionLogger;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.transaction.Transaction;import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;public abstract class BaseExecutor implements Executor {protected Transaction transaction;protected Executor wrapper;protected Configuration configuration;protected int queryStack;protected BaseExecutor(Configuration configuration, Transaction transaction) {this.transaction = transaction;this.configuration = configuration;this.wrapper = this;}@Overridepublic <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException {return null;}@Overridepublic void commit(boolean required) throws SQLException {}@Overridepublic void rollback(boolean required) throws SQLException {}@Overridepublic CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql) {return null;}@Overridepublic Transaction getTransaction() {return null;}@Overridepublic void setExecutorWrapper(Executor var1) {this.wrapper = wrapper;}protected Connection getConnection(Log statementLog) throws SQLException {Connection connection = transaction.getConnection();if (statementLog.isDebugEnabled()) {return ConnectionLogger.newInstance(connection, statementLog, queryStack);} else {return connection;}}}

package org.apache.ibatis.executor;import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.transaction.Transaction;import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;public class SimpleExecutor extends BaseExecutor {protected SimpleExecutor(Configuration configuration, Transaction transaction) {super(configuration, transaction);}private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {Statement stmt;Connection connection = getConnection(statementLog);stmt = handler.prepare(connection, transaction.getTimeout());handler.parameterize(stmt);return stmt;}}

package org.apache.ibatis.executor;import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.cache.TransactionalCacheManager;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.transaction.Transaction;import java.sql.SQLException;
import java.util.List;public class CachingExecutor implements Executor{private final Executor delegate;private final TransactionalCacheManager tcm = new TransactionalCacheManager();public CachingExecutor(Executor delegate) {this.delegate = delegate;delegate.setExecutorWrapper(this);}@Overridepublic <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException {return null;}@Overridepublic void commit(boolean required) throws SQLException {}@Overridepublic void rollback(boolean required) throws SQLException {}@Overridepublic CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql) {return null;}@Overridepublic Transaction getTransaction() {return null;}@Overridepublic void setExecutorWrapper(Executor var1) {throw new UnsupportedOperationException("This method should not be called");}
}

package org.apache.ibatis.session;import org.apache.ibatis.executor.*;
import org.apache.ibatis.plugin.InterceptorChain;
import org.apache.ibatis.transaction.Transaction;public class Configuration {private Configuration conf;public Configuration(Configuration conf){this.conf = conf;}protected boolean cacheEnabled = true;protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;protected final InterceptorChain interceptorChain = new InterceptorChain();public Executor newExecutor(Transaction transaction, ExecutorType executorType) {executorType = executorType == null ? defaultExecutorType : executorType;executorType = executorType == null ? ExecutorType.SIMPLE : executorType;Executor executor;if (ExecutorType.BATCH == executorType) {executor = new BatchExecutor(this, transaction);} else if (ExecutorType.REUSE == executorType) {executor = new ReuseExecutor(this, transaction);} else {executor = new SimpleExecutor(conf, transaction);}if (cacheEnabled) {executor = new CachingExecutor(executor);}executor = (Executor) interceptorChain.pluginAll(executor);return executor;}
}

  

转载于:https://www.cnblogs.com/jiangyaxiong1990/p/9236764.html

设计模式(装饰模式)相关推荐

  1. 设计模式----装饰模式

    设计模式--装饰模式 "装饰模式(Decorator)"又名"包装模式(Wrapper)",通常用来灵活地扩充对象的功能. 在此之前我们可以通过类的继承来扩充父 ...

  2. 大话设计模式-装饰模式(大鸟和小菜Java版)

    装饰模式:装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象.(百度百科) 这个模式让后期的修改变得极为简单,真的就高内 ...

  3. 大话设计模式—装饰模式

    装饰模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装原 ...

  4. 设计模式--装饰模式

    目录 什么是装饰模式? 应用代码示例 装饰模式模板 jdk中的装饰模式 为什么装饰器类不能直接实现Component父类? 什么是装饰模式? 以生活中的场景来举例,一个蛋糕胚,给它涂上奶油就变成了奶油 ...

  5. C++设计模式-装饰模式

    目录 基本概念 代码和实例 基本概念 装饰模式是为已有功能动态地添加更多功能的一种方式. 当系统需要新功能的时候,是向旧系统的类中添加新代码.这些新代码通常装饰了原有类的核心职责或主要行为. 装饰模式 ...

  6. 李建忠设计模式——装饰模式

    1."单一职责"模式 在软件组件的设计中,如果责任划分不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任. 典型模式 Deco ...

  7. C++设计模式——装饰模式(高屋建瓴)

    原网址:https://blog.csdn.net/CoderAldrich/article/details/83115394 重点在于 ConcreteDecoratorA(Component *d ...

  8. java设计模式——装饰模式

    装饰模式也称为包装模式.结构型设计模式之一,其使用一种对客户端透明的方式动态的扩展对象的功能,同时它也是继承关系的一种替代方案之一. 装饰模式可以动态的给一个对象添加一些额外的职责.就增加功能功能来说 ...

  9. 设计模式——装饰模式详解

    0. 前言   写在最前面,本人的设计模式类博文,建议先看博文前半部分的理论介绍,再看后半部分的实例分析,最后再返回来复习一遍理论介绍,这时候你就会发现我在重点处标红的用心,对于帮助你理解设计模式有奇 ...

  10. 设计模式 | 装饰模式

    1 | 装饰模式的概述 我们在了解装饰模式之前,先回顾下生活中的几个常见现象,举例如下: 新房的装修,房屋装修并没有改变房屋居住的本质,但可以让房屋变得更漂亮,更温馨,更实用,更满足居家需求. 相片的 ...

最新文章

  1. Sprinig泛型依赖注入
  2. 吴恩达Coursera机器学习 - Chapter 1 引言
  3. 用c语言递归函数做扫雷,【C语言基础学习---扫雷游戏】(包含普通版+递归炼狱版)...
  4. Java try catch finally语句
  5. android jni arm x86,使用houdini(Android模拟器)在基于x86的AVD上运行ARM库
  6. Python使用marshal模块操作二进制文件
  7. java 8进制 前是 零,从零学java笔录-第6篇 进制之间转换
  8. 非关系数据库-NoSQL探讨
  9. ubuntu20.04安装nvidia显卡驱动/CUDA/cuDNN
  10. 拉格朗日插值的优缺点_对拉格朗日插值法与牛顿插值法的学习和比较
  11. 【DM642】ICELL Interface—Cells as Algorithm Containers
  12. 高中英语语法(002)-否定
  13. 单片机测量脉宽c语言程序,利用51系列单片机定时器功能实现测量脉冲宽度
  14. virt-install安装虚拟机
  15. 小丑改造计划之动态规划
  16. 微信php页面你画我猜,微信小程序你画我猜
  17. 20170604第四讲
  18. DTT年度收官圆桌π,华为云8位技术专家的年末盘点
  19. 使用Plsql+oracle client 连接 Oracle数据库
  20. SharePoint 2010 安装错误:请重新启动计算机,然后运行安装程序以继续

热门文章

  1. win cmd rmdir /s递归删除目录
  2. Linux磁盘阵列raid1和raid5相关概念及其实现途径
  3. k8s强制删除一直处于terminating状态的pod
  4. Linux vim剪切/删除命令(结合p粘贴使用就是剪切)
  5. Java线程池示例:并行计算200000以内的质数个数
  6. 【软考】2017年11月软件设计师上午真题1-4题答案解析
  7. Qt for Android调用原生接口打开相机拍照并存储照片
  8. ifconfig 命令找不到解决
  9. JDK,JRE和JVM三者的关系以及java的运行机制,环境变量,三大版本,特点
  10. 小牛照片恢复软件_电脑移动硬盘U盘数据恢复SD卡照片文件软件修复开盘远程维修服务...