结构型模式-装饰模式

视频审核中。。

定义

装饰者模式又名包装模式。动态的给一个对象添加一些额外的职责。

装饰者模式适用场景:

(1)以动态的方式给对象添加职责。

(2)处理那些可以撤销的职责。

(3)当采用生成子类的方法进行扩充时,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。

装饰模式一共有四个角色。

 

 

(1)抽象组件(Component):给出一个抽象接口,以规范准备接受附加责任的对象。

(2)被装饰者(ConcreteComponent):Component的具体实现,也就是我们要装饰的具体对象。

(3)装饰者组件(Decorator):持有组件对象的实例引用,该类的职责就是为了装饰具体组件对象,定义的基类。

(4)具体装饰(ConcreteDecorator):负责给构件对象装饰附加的功能。

 举个栗子

比如说我们去买蛋糕,蛋糕可以装饰成不同的水果蛋糕。

 第一步:定义蛋糕接口(Component)

public interface Cake {
    // 蛋糕名字
    String cakeName();
    // 蛋糕价格
    int cakePrice();
}

第二步:定义两种不同形状的蛋糕:圆形蛋糕和正方形蛋糕(ConcreteComponent)

public class CircleCake implements Cake {
    @Override
    public String cakeName() {
        return "圆形蛋糕";
    }

    @Override
    public int cakePrice() {
        return 46;
    }
}

public class RectangleCake implements Cake {
    @Override
    public String cakeName() {
        return "正方形蛋糕";
    }

    @Override
    public int cakePrice() {
        return 52;
    }
}

第三步:定义蛋糕口味抽象类(Decorator)

public abstract class TasteDecorator implements Cake {
    // 具体蛋糕name由子类定义
    @Override
    public abstract String cakeName();

    // 具体蛋糕价格由子类定义
    @Override
    public abstract int cakePrice();
}

第四步:具体蛋糕口味(ConcreteDecorator):加芒果和草莓

public class AddMangoTaste extends TasteDecorator {

    private String description = "蛋糕加芒果";
    private Cake cake = null;

    public AddMangoTaste(Cake cake){
        this.cake = cake;
    }

    // 为蛋糕加芒果
    @Override
    public String cakeName() {
        return cake.cakeName() + " " + description;
    }

    // 价格增加10元
    @Override
    public int cakePrice() {
        return cake.cakePrice() + 10;
    }
}

public class AddStrawberryTaste extends TasteDecorator{

    private String description = "蛋糕加草莓";
    private Cake cake = null;

    public AddStrawberryTaste(Cake cake){
        this.cake = cake;
    }

    // 为蛋糕加草莓
    @Override
    public String cakeName() {
        return cake.cakeName() + " " + description;
    }

    // 价格增加15元
    @Override
    public int cakePrice() {
        return cake.cakePrice() + 15;
    }
}

第五步:模拟客户买蛋糕

public class Client {
    public static void main(String[] args) {
        Cake circleCake = new CircleCake();
        System.out.println(circleCake.cakeName() + ":" + circleCake.cakePrice());
        Cake rectangleCake = new RectangleCake();
        System.out.println(rectangleCake.cakeName() + ":" + rectangleCake.cakePrice());

        circleCake = new AddMangoTaste(circleCake);
        System.out.println(circleCake.cakeName() + ":" + circleCake.cakePrice());
        rectangleCake = new AddStrawberryTaste(rectangleCake);
        System.out.println(rectangleCake.cakeName() + ":" + rectangleCake.cakePrice());
    }
}

结果:

 

 

装饰者模式的优缺点

优点:

1、目的在于扩展对象的功能。装饰者模式提供比继承更好的灵活性。装饰是动态的,运行时可以修改的;继承是静态的,编译期便已确定好。

2、通过使用不同的装饰类及对他们的排列组合,可以创造出许多不同行为的组合。

缺点:

1、 产生很多的小对象,大量的小对象会占用内存。

2、 组合方式很多,很容易出错。

posted @ 2020-04-08 14:18  涤生-  阅读(159)  评论(0编辑  收藏  举报