一文读懂设计模式--装饰者模式

装饰者模式可以给已经存在的对象基础上动态的增强,也就是在不改变之前源码的基础上进行增强。
满足开闭原则。

开闭原则顾名思义就是:对扩展开放,对修改关闭。我们在想要扩展功能的时候,不能通过修改源码的方式,而必须通过扩展的方式。

装饰者模式实现

通过一个简单的例子来说明什么是装饰者模式。

我们目前有一个Person类,他有一个吃饭的功能,但是在之前的代码之后,技术经理非要让我们添加功能,比如想在吃饭之前河口啤酒,这可如何是好呀?难道去修改源码?

那显然不行,首先为了尽量让我们的代码互相兼容(代码功能都变了,显然不兼容),另外一个就是要满足开闭原则(使用扩展的方式来增加功能)。这可以通过装饰者模式来实现。

下边看具体代码实现:

我们定义一个接口实现人的吃饭功能:
一文读懂设计模式--装饰者模式_第1张图片
之后定义一个被装饰的子类对象:
一文读懂设计模式--装饰者模式_第2张图片
这样就能实现一个人吃麻辣香锅的功能了。测试如下:
一文读懂设计模式--装饰者模式_第3张图片
执行结果:
在这里插入图片描述
但是如果我们想改变之前的逻辑,一个人在吃饭的时候还要喝啤酒呢?

如何更加优雅的在不改变源码的基础上修改之前的功能呢?

这就要用到今天所讲的装饰者模式了,我们可以定义一个装饰者类,对原来的对象进行装饰,然后调用这个装饰者对象就可以了。

定义的装饰者如下:

/**
 * @author xxy
 * @date 2020/7/20
 * 对Person的子类进行装饰
 */
public class ManDecorator implements Person {
    private Person person;

    ManDecorator(Person person) {
        this.person = person;
    }

    @Override
    public void eat() {
        System.out.println("吃饭之前喝点啤酒...");
        person.eat();
    }
}

然后我们在调用装饰者对象帮我们完成功能就可以了,测试类如下:

/**
 * @author xxy
 * @date 2020/7/20
 * 测试类
 */
public class Test {
    public static void main(String[] args) {
        Person man = new Man();
        //man.eat();
        Person manDecorator = new ManDecorator(man);//装饰者对象
        manDecorator.eat();
    }
}

这样就能在不修改源码的基础上对之前的方法进行增强了。

此时如果想要对原来的方法增加其他的功能,同样也可以编写其他的装饰对象,每次都调用这个装饰者对象就可以了。比如:吃饭前洗手,吃饭后打扫卫生等等。

细节

这里要注意一个细节,就是我们的装饰者也要实现被装饰对象所实现的接口,这样就能使用多态的方式面向接口编程,在被装饰之后依旧返回一个接口引用,使其他类感知不到我们装饰者的存在。

比如我们上边的如果不使用装饰对象,那么会返回一个Person接口的引用,正因为我们的装饰者对象也实现了Person接口,所以能够在对方法增强的基础上依旧返回一个Person对象,如果其他类想要使用这个Man类的话,我们可以以Person接口引用的方式传过去,让对方感觉不到已经被装饰过了。

好处

那么为什么要使用装饰者模式呢?

同一个接口,一个类在另外一个类基础上实现增强方法,以前是采用继承,为什么要采用装饰者模式

类继承一旦父类改变,那么子类也得相应进行改变,也就是说它们之间的耦合性太高,不利于代码的维护和管理,使用装饰者模式可以将装饰类和被装饰类彼此独立起来,只需要实现共同的接口,一旦需要改代码升级时,只需要更改相应的类就可以了,不需要都改变。

总的来说:使用装饰者模式就是为了:解耦以及提高代码的扩展性和可维护性。

你可能感兴趣的:(设计模式,设计模式,面向对象编程,java)