装饰者模式介绍

文章参考码农翻身的例子进行解释。
装饰者模式又名包装(Wrapper)模式。装饰者模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。

装饰者模式动态地将责任附加到对象身上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

没有应用场景这样说是可能没什么感觉。

这里我们假设我们的项目按照业务分模块,假定我们有用户管理模块、订单管理模块、支付管理模块,这几个业务模块都需要日志模块输出日志,安全模块进行加密,事物模块、性能统计模块

这些通用性的非功能性需求是几个业务模块都需要的,跨模块的。如图
java设计模式之装饰者模式
拿我们的订单模块来说,他的代码实现有可能会这样

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();
这样就可以使用任意数量的装饰器,任意次序执行。

相关文章: