欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > asp.net >内容正文

asp.net

设计模式(装饰模式)

发布时间:2024/10/12 asp.net 117 豆豆
生活随笔 收集整理的这篇文章主要介绍了 设计模式(装饰模式) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

什么是装饰模式(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

总结

以上是生活随笔为你收集整理的设计模式(装饰模式)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。