设计模式(装饰模式) -凯发k8官方网
什么是装饰模式(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;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
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
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
总结
以上是凯发k8官方网为你收集整理的设计模式(装饰模式)的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇:
- 下一篇: