设计模式之装饰者模式

个人理解,如有错误,请大家指正,谢谢。

什么是装饰者模式?

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

怎么理解呢?比如说,我们想建立一个洋娃娃类,娃娃可以穿衣服、裤子、裙子、以及同时穿裤子和衣服......

有几种实现方案:

version1:

娃娃作为父类,芭比娃娃作为子类,芭比娃娃的子类有:穿衣服的芭比娃娃、穿裤子的芭比娃娃、穿裙子的芭比娃娃、同时穿衣服和裤子的芭比娃娃......是不是太多类了?除此之外,如果我们新研发出一种噼啪娃娃,那么将会......

这样的代码想一想就很恶心对不对?我们是负责任的开发人员,当然不愿写出这样不易扩展、难以维护的代码。

那么应该怎么办呢?

version2:

那么可否在Doll类中加上各种衣服的属性?先不忙着写代码,我们想一想这样会出现什么问题。

问题一:如果由新制造了一款不需要穿衣服的呱唧娃娃,那么呱唧娃娃类继承Doll,也会继承到对它来说毫无意义的各种衣服属性。

问题二:如果某个娃娃比较有个性,非要同时穿两件一样的衣服,应该怎么实现?

看来,这种方案也并不合适。

version3:装饰者模式:

我们可以用Skirt把BaBi Doll包一层,再用Pants把穿了裙子的Babi Doll包一层。

不知道我有没有说清楚,大家请看一下UML图:

我们可以看到,装饰者继承了被装饰者,因此他们是一样的类型。装饰者模式中,继承的目的是为了达到“类型匹配”,而不是获得”行为“,”行为“来自装饰者和基础组件,基础组件也可能是其他装饰者。这里不理解的同学可以继续往下看,将我们的测试类代码看完之后,再回味一下这里。

好了,下面我们来写代码。

我们先写Doll类,这是一个抽象类:

public abstract class Doll {

    protected String name;

    public String getName() {
        return name;
    }
}

Doll的子类,芭比娃娃类:

public class Babi extends Doll {

    public Babi() {
        name = "a babi doll";
    }
}

装饰者抽象类:

public abstract class Decorator extends Doll {

    public abstract String getName();
}

Skirt类:

public class Skirt extends Decorator {

    private Doll doll;

    public Skirt(Doll doll) {
        this.doll = doll;
    }
    
    @Override
    public String getName() {
        return doll.getName() + " with skirt";
    }
}

Pants类:

public class Pants extends Decorator {

    private Doll doll;

    public Pants(Doll doll) {
        this.doll = doll;
    }

    @Override
    public String getName() {
        return doll.getName() + " with pants";
    }
}

大功告成!下面是我们的测试类:

public class Test {

    public static void main(String[] args) {
        Doll doll = new Babi();
        System.out.println(doll.getName());

        doll = new Skirt(doll);
        System.out.println(doll.getName());

        doll = new Pants(doll);
        System.out.println(doll.getName());
    }
}

写到这里,我们仔细的看一下测试类,就会发现,最后doll由最初的Doll类变成了Pants类,用装饰者包装,会造成类型的改变。因此,依赖于具体组件类型的代码不适用于装饰者模式,而装饰者模式适用于依赖抽象组件类型的代码。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值