装饰者模式介绍
文章参考码农翻身的例子进行解释。
装饰者模式又名包装(Wrapper)模式。装饰者模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。
装饰者模式动态地将责任附加到对象身上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
没有应用场景这样说是可能没什么感觉。
这里我们假设我们的项目按照业务分模块,假定我们有用户管理模块、订单管理模块、支付管理模块,这几个业务模块都需要日志模块输出日志,安全模块进行加密,事物模块、性能统计模块。
这些通用性的非功能性需求是几个业务模块都需要的,跨模块的。如图
拿我们的订单模块来说,他的代码实现有可能会这样
public class PlaceOrderCommand {
/**
* chuli
*/
public void execute() {
//日志处理
Logger logger = new Logger();
logger.log();
//性能统计
Perforamce perforamce = new Perforamce();
perforamce.doing();
benginTransition();
//TODO:进行订单业务处理
endTransition();
}
}
然后我们其他模块也需要这么做,就会发现代码重复太多了。此时我们会想到抽象出来共有的,让各种具体的业务类去实现具体的业务
public abstract class BaseCommond {
public void execute() {
//日志处理
Logger logger = new Logger();
logger.log();
//性能统计
Perforamce perforamce = new Perforamce();
perforamce.doing();
benginTransition();
doingBussiness();
endTransition();
}
abstract void doingBussiness();
如上doingBussiness();就是具体的业务,哪个业务去继承,就在此作方法做具体的业务。
但此方法有个巨大的缺点:父类定义了一切,要执行那些代码,以什么顺序执行等等都被固定,无法更改。
此时我们的装饰者模式便可以派上用场了
public interface Command {
public void excute();
}
记录日志装饰器
public class LoggerDecorator implements Command {
Command mCommand;
public LoggerDecorator(Command command) {
mCommand = command;
}
@Override
public void excute() {
//TODO:做这个装饰要做的事情
Logger logger=Logger.getLogger("my");
Log.d("mytag","LoggerDecorator");
mCommand.excute();
}
}
性能统计装饰器
public class PerformanceDecorator implements Command {
Command mCommand;
public PerformanceDecorator(Command command) {
mCommand = command;
}
@Override
public void excute() {
//TODO:做这个装饰要做的事情
Log.d("mytag","PerformanceDecorator");
mCommand.excute();
}
}
具体的业务
public class PlaceOrderCommant implements Command {
@Override
public void excute() {
//TODO:做这个装饰要做的事情
}
}
现在我们让这个业务能够打印日志、性能统计
LoggerDecorator loggerDecorator = new LoggerDecorator(
new PerformanceDecorator(new PlaceOrderCommand()));
loggerDecorator.excute();
这样就可以使用任意数量的装饰器,任意次序执行。