对装饰器模式的理解

        我们为什么使用装饰器模式?

使用装饰器模式能在不改变源代码的基础上,对源代码的功能进行拓展,即为一个类添加一些功能,同时又不希望改变这个类原来的结构。我举以下例子进行说明。

例如:我已经完成了一个日志的接口和它的各个实现类,但是这些类只有输出日志到不同地方的功能,LoggerFileSystem能将日志输出到文件系统(磁盘)中,LoggerCloud能将日志输出到云端的某个文件中。现在新需求来了,假如我想要在每条日志输出后顺带输出这条日志的时间,我们把它假设为功能一(functionOne);假如我还想再此基础上输出日志内容,我们把它假设为功能二(functionTwo)。我们为日志添加了功能而我们不想去修改每个实现类的方法,这时候就能使用装饰者模式,为这个接口编写一个装饰类,修饰原来的日志输出。


log()定义日志输出的方法

/**
 * Created by AQ on 2018/7/11.
 */
public interface Logger {
    public void log();
}

LoggerCloud和LoggerFileSystem为原有的结构(我们未对日志功能进行拓展时已存在)

/**
 * Created by AQ on 2018/7/11.
 */
public class LoggerCloud implements Logger {

    @Override
    public void log() {
        System.out.println("Log in Cloud");
    }
}
/**
 * Created by AQ on 2018/7/11.
 */
public class LoggerFileSystem implements Logger {
    @Override
    public void log() {
        System.out.println("Log in FileSystem");
    }
}

为Logger编写一个装饰器,拓展log()的功能,这个装饰类要实现Logger接口并且拥有一个Logger成员

/**
 * Created by AQ on 2018/7/11.
 */
public class Decorator implements Logger {

    protected Logger logger;

    Decorator(Logger logger){
        this.logger=logger;
    }

    @Override
    public void log() {
        if(logger!=null){
            logger.log();
        }
    }
}

FunctionOne和FunctionTwo的newFunction()即我们想要添加的功能

/**
 * Created by AQ on 2018/7/11.
 */
public class FunctionTwo extends Decorator {

    FunctionTwo(Logger logger) {
        super(logger);
    }

    @Override
    public void log() {
        super.log();
        functionTwo();
    }

    public void functionTwo(){
        System.out.println("new function two");
    }
}

/**
 * Created by AQ on 2018/7/11.
 */
public class FunctionOne extends Decorator {

    FunctionOne(Logger logger) {
        super(logger);
    }


    public void newFunction(){
        System.out.println("new function one");
    }

    @Override
    public void log() {
        super.log();
        newFunction();
    }
}

main方法

public class Main {

    public static void main(String[] args) {
        Logger logger = new LoggerCloud();
        logger.log();
        System.out.println();
        Logger logger1 = new FunctionOne(logger);
        logger1.log();
        System.out.println();
        Logger logger2 = new FunctionTwo(logger1);
        logger2.log();
    }
}

输出结果为

Log in Cloud

Log in Cloud
new function one

Log in Cloud
new function one
new function two

        结果分析

logger.log()调用的是LoggerCloud类中log()方法,输出 Log in Cloud

logger1.log()调用的是FunctionOne类中的log()方法,先运行super.log(),即FunctionOne的父类Decorator的log()方法,由于在构造logger1时传入的值是logger,所以此时Decorator的log()方法运行的是logger.log(),输出Log in Cloud。然后运行到logger1.log()中的newFunction(),输出new function one。

logger2.log()调用的是FunctionTwo类中的log()方法,先运行super.log(),即FunctionTwo的父类Decorator的log()方法,由于在构造logger2时传入的值是logger1,所以此时Decorator的log()方法运行的是logger1.log(),

输出 Log in Cloud

       new function one

然后运行到logger2.log()中的newFunction(),

        输出new function two。


本文参考了https://blog.csdn.net/qq_24448899/article/details/78068813

猜你喜欢

转载自blog.csdn.net/chaos_le/article/details/81007164
今日推荐