设计模式——装饰模式

Posted tujietg

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式——装饰模式相关的知识,希望对你有一定的参考价值。

定义:

装饰模式(Decorator),在不改变对象的前提下,动态给对象增加一些功能。

对于,增加功能而言,装饰者模式比增加子类更灵活。

如果想给一个特定的类A增加功能,我们一般采用两种模式:

1,继承该A,利用其子类在实现这个A的函数的同时,增加一些新的方法。这个方法是静态的,我们不能通过继承来实现动态的匹配。

而且,当类比较多的时候,容易发生类爆炸。(下面的例子会解析类爆炸)

2,利用装饰模式,给类一个抽象类B,让装饰类D和类A同时继承与这个抽象类B。

通过装饰类D和类A的组合来达到为类A增加功能的目的。这样的增加是动态的。随意我们在客户端组合的。

UML图:

技术分享图片

Demo:

业务场景:一个人(男人)去买帽子。(帽子可能是红的,黑的,白的,嗯...绿的~)总之男生去买的帽子不知道几个,而且不知道颜色。

解决方案:

1,通过类的继承,如果我们给每种可能去创建一个类的话,那就出现了类爆炸了。

2,当我们使用装饰模式的时候。我们可以动态的组装其购买。

废话不多说,代码里来参悟!

超级父类(超类):

public abstract class Person {
    String description;

    public String getDescription() {
        return description;
    }

    // 计算其花了多少钱
    public abstract int cost();
}

被修饰的类:(man)

public class Man extends Person {

    public Man() {
        description = "这个男生";
    }

    @Override
    public int cost() {
        return 0;
    }

}

抽象修饰类:(为了迎合我们的开放封闭原则,定义一个抽象类,毕竟以后店家除了绿帽子还会出售其他的颜色帽子)

public abstract class Hat extends Person {
    public abstract String getDescription();
}

修饰类:(多个)

public class RedHat extends Hat {

    Person person;

    public RedHat(Person person) {
        super();
        this.person = person;
    }

    @Override
    public String getDescription() {

        return person.getDescription() + "买了红帽子";
    }

    @Override
    public int cost() {
        return person.cost() + 1;
    }

}
public class BlackHat extends Hat {
    Person person;

    public BlackHat(Person person) {
        super();
        this.person = person;
    }

    @Override
    public String getDescription() {
        return person.getDescription() + "买了黑帽子";
    }

    @Override
    public int cost() {
        // TODO Auto-generated method stub
        return person.cost() + 100;
    }

}

等各种颜色的帽子。

客户端:

public class Client {
    public static void main(String[] args) {
        // 实力化被装饰者(man)
        Person person = new Man();
        person = new RedHat(person);
        person = new BlackHat(person);
        System.out.println(person.getDescription() + "花费了" + person.cost());
    }
}

利用装饰模式,我们就可以很好的实现了男生购物车的拼接~

总结:

如果给一个类很多的功能,我们可以采取继承,但是如果我们需要很多功能的之间的灵活的组合,如果还是采用继承的话,我们就要创建N多的子类,这样就形成了类爆炸了。

但是,如果我们采用装饰模式来解决的话,只需要为每个功能创建一个修饰类,客户端根据需求直接组装不同的对象就好啦。灵活性得到了很大的提升~

 

以上是关于设计模式——装饰模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式---装饰者模式

设计模式之单例模式

Java设计模式之装饰者模式

装饰模式与代理模式的区别

设计模式之装饰器模式

设计模式-装饰者模式(Go语言描述)