Decorator模式

Decorator译为装饰,生活中有很多装饰器模式的例子。比如你去买手抓饼,可以加料,当然最重要的是它是手抓饼。老板不可能把所有类型的手抓饼都做好,而是根据你的需要,比如你要加培根和鸡蛋,再加肉松,老板则煎好饼,再把料放好,把料放进饼里就是对饼的一种“装饰”。当然,你也可以把装好的手抓饼让老板再加点其他的料(当然现实中不会这样)。

所谓装饰器模式,即将被装饰对象,对应上面例子的饼,用其他的料给它 “装饰” 让它不仅仅是饼,而是具有了相比于被装饰对象更多的功能。

下面就以上面的手抓饼为例,具体看看装饰器模式。

涉及的类

AddMaterial用于做出手抓饼的抽象类
Cake饼,被修饰对象
Materials料的抽象类
Baken给饼加培根
Egg给饼加鸡蛋

类图

 Cake类

Cake类即代表饼类,为 被装饰的类,该类继承了AddMaterial(抽象类)类,该类在下面介绍。在Cake类中重写了抽象父类的getCake方法,返回 “饼” 字符串。

public class Cake extends AddMaterial{
    @Override
    String getCake() {
        return "饼";
    }
}

AddMaterial类

该类为抽象类(也可以设计为接口),是为了 统一被装饰的类与装饰类,使得 被装饰的类的对象实例被装饰类装饰后仍然能够保持接口(API)的透明性(可参考结城浩《图解设计模式》)。该类声明了一个抽象方法 getCake ,供子类去重写其中的逻辑。

abstract class AddMaterial {
    abstract String getCake();
}

Materials类

在AddMaterial 类之下,并不是直接由具体的材料类继承,而是先抽象出一个材料类,在本类中聚合其父类AddMaterial,并在本类构造器初始化AddMaterial的子类,这样子具体的子类可以继承该属性,并可以调用该子类的方法。

abstract class Materials extends AddMaterial{
    protected AddMaterial addMaterial;

    public Materials(AddMaterial addMaterial) {
        this.addMaterial = addMaterial;
    }
}

Egg类

Egg类是Materials类的具体实现子类,重写了getCake方法,并使用了Materials类聚合的AddMaterial。在Egg类中,getCake方法调用了addMaterial类的getCake方法,可能是调用 被装饰的类Cake也可能是来自一个装饰类(装饰了被装饰类)

public class Egg extends Materials{
    public Egg(AddMaterial addMaterial) {
        super(addMaterial);
    }

    @Override
    String getCake() {
        return addMaterial.getCake() + "-" + "鸡蛋";
    }
}

Baken类

Baken类也是Materials类的具体实现类,和上面Egg类相同。

public class Baken extends Materials{
    public Baken(AddMaterial addMaterial) {
        super(addMaterial);
    }

    @Override
    String getCake() {
        return addMaterial.getCake() + "-" + "培根";
    }
}

Main类

Main类中,创建了基本的 被装饰的对象 Cake,再创建了Baken并将Cake放入,这就是将cake使用培根 装饰 cake,接着将被培根装饰的cake再放入Egg类的构造器中,得到由Egg和Baken装饰的cake。

public class Main{
    public static void main(String[] args) {
        AddMaterial cake = new Cake();
        AddMaterial bakenAndCake = new Baken(cake);
        AddMaterial eggAndCakeAndBaken = new Egg(bakenAndCake);
        AddMaterial eggAndCake = new Egg(cake);
        System.out.println(eggAndCakeAndBaken.getCake());
        System.out.println(eggAndCake.getCake());
    }
}

输出结果:

饼-培根-鸡蛋
饼-鸡蛋

学习结城浩《图解设计模式》记

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值