文章目录

概念

装饰器模式可以动态地将一些属性、能力添加到一个对象上。若要扩展功能,装饰器提供了比继承更具有弹性的方式。

装饰器模式类图:

image

例子

如果大家看过变形金刚2,应该还记得电影后期擎天柱接受了一个老霸天虎(好像是吧)的翅膀等一系列零件,从而具备了飞行的能力。通过这个例子就能很好地理解装饰器模式

首先是变形金刚的接口

public interface Transformer{
    public String show();
}

然后是擎天柱这个变形金刚的实现类:

public class OptimusPrime implements Transformer{
    @Override
    public String show(){
        System.out.println("擎天柱");
        return "擎天柱";
    }
}

装饰器的超类:

public class TransformerDecorater implements Transformer{
    protected Transformer transformer;
    public TransformerDecorater(Transformer transformer){
        this.transformer = transformer;
    }
}

具体的装饰器,如翅膀:

public class WingTransformer extends TransformerDecorater{
    public WingTransformer(Transformer transformer){
        super(transformer);
    }
    @Override
    public String show(){
        String last = this.transformer.show() + "(飞行)";
        System.out.println(last);
        return last;
    }
}

测试:

Transformer optimus-prime = new OptimusPrime();
optimus-prime = new WingTransformer(optimus-prime);
optimus-prime.show();
// 擎天柱
// 擎天柱(飞行)

分析

在上述例子中,OptimusPrime类是被装饰的类,而WingTransformer则是装饰器。

其实所谓装饰器就是带有“装饰物”的父类。以上面的例子来说,WingTransformer就是“带有翅膀的变形金刚”,而具体这个变形金刚是谁,则需要通过传入一个Transformer类对象来予以确定(既然是Transformer类,那么传入实现了Transformer的装饰器也是可以的,那就是多重修饰)。

那我们为WingTransformer的构造函数传入了“擎天柱”的实例(optimus-prime),那么此时的optimus-prime就代表了“一个带有翅膀的变形金刚,而这个变形金刚是擎天柱”。

所以

Transformer optimus-prime = new OptimusPrime();
optimus-prime = new WingTransformer(optimus-prime);

就等价为

Transformer optimus-prime = new WingTransformer(new OptimusPrime());

总结

可能有人有疑问说“这跟子类有什么区别呢?”在上述的例子中,我们可以声明一个WingOptimusPrime的子类来创建一个会飞的“擎天柱”。

当然,在只有“擎天柱”这一种变形金刚的情况下似乎没有什么区别。可是变形金刚不仅只有“擎天柱”一种,还有“大黄蜂”、“铁皮”等等。我们可以为每一种变形金刚都编写一个子类,但那样做过于麻烦。而使用装饰器则没有这个困扰。

Logo

尧米是由西云算力与CSDN联合运营的AI算力和模型开源社区品牌,为基于DaModel智算平台的AI应用企业和泛AI开发者提供技术交流与成果转化平台。

更多推荐