装饰模式(Decorator)

一、概念ide

装饰模式动态地给一个对象添加一些额外的职责。就扩展功能而言,它比生成子类方式更为灵活,属于结构性模式一种。
学习

二、模式结构this

  • 抽象组件角色(Component):定义一个对象接口,以规范准备接受附加责任的对象,便可以给这些对象动态地添加职责。
  • 具体组件角色(ConcreteComponent) :被装饰者,定义一个将要被装饰增长功能的类。能够给这个类的对象添加一些职责。
  • 抽象装饰器(Decorator):维持一个指向构件Component对象的实例,并定义一个与抽象组件角色Component接口一致的接口。
  • 具体装饰器角色(ConcreteDecorator):向组件添加职责。

三、使用场景调试

  • 在不影响其余对象的状况下,以动态、透明的方式给单个对象添加职责
  • 须要动态地给一个对象增长功能,这些功能也能够动态地被撤销
  • 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。不能采用继承的状况主要有两类:第一类是系统中存在大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增加;第二类是由于类定义不能继承(如final类)

四、优缺点code

优势:cdn

  • 装饰模式能够提供比继承更多的灵活性
  • 经过配置文件能够在运行时选择不一样的装饰器,从而实现不一样的行为
  • 使用不一样的具体装饰类以及这些装饰类的排列组合,能够创造出不少不一样行为的组合
  • 具体构件类与具体装饰类能够独立变化,原有代码无须改变,符合“开闭原则”

缺点:对象

  • 装饰类和小对象的产生将增长系统的复杂度,加大学习与理解的难度
  • 屡次装饰的对象,调试时寻找错误可能须要逐级排查,较为烦琐

五、实例继承

在购买奶茶的时候,常常会有选择配料的选项,每种配料的价格不同,能够多种组合,价格也不同。首先先定义奶茶的接口,具备名称和价格方法接口

public interface IMilkTea {

    String name();

    double price();
}

继承IMilkTea的相关茶类class

public class RedTea implements IMilkTea {

    @Override
    public String name() {
        return "红茶";
    }

    @Override
    public double price() {
        return 10;
    }
}
public class GreenTea implements IMilkTea {

    @Override
    public String name() {
        return "绿茶";
    }

    @Override
    public double price() {
        return 12;
    }
}

定义具体装饰类Decorator,装饰相关奶茶

public class Decorator implements IMilkTea {

    @Override
    public String name() {
        return null;
    }

    @Override
    public double price() {
        return 0;
    }
}

继承Decorator的相关类

public class IceCream extends Decorator {

    private String name = "加雪糕";
    private IMilkTea milkTea;

    public IceCream(IMilkTea milkTea) {
        this.milkTea = milkTea;
    }

    @Override
    public String name() {
        return milkTea.name() + name;
    }

    @Override
    public double price() {
        return milkTea.price() + 3;
    }
}
public class Pearl extends Decorator {
    private String name = "加珍珠";
    private IMilkTea milkTea;

    public Pearl(IMilkTea milkTea) {
        this.milkTea = milkTea;
    }

    @Override
    public String name() {
        return milkTea.name() + name;
    }

    @Override
    public double price() {
        return milkTea.price() + 2;
    }
}

客户端使用

public static void main(String[] args) {
    IMilkTea milkTea = new RedTea();
    milkTea = new IceCream(milkTea);
    milkTea = new Pearl(milkTea);
    System.out.println(milkTea.name() + "\n价格:" + milkTea.price());
}
相关文章
相关标签/搜索