设计模式-装饰者模式

2023-05-04 14:21:56 浏览数 (1)

装饰者模式是一种结构型设计模式,它允许在不改变对象结构的情况下,动态地添加行为或修改现有行为。在该模式中,通常将核心对象称为“组件”,并且将新增的行为称为“装饰者”。

使用装饰者模式的好处是可以将对象的功能拆分成多个小的、单一的职责,从而使每个职责都可以进行独立的扩展和修改,而不会对其他职责造成影响。此外,装饰者模式还可以避免使用继承带来的类爆炸问题,使得代码更加灵活和易于维护。

假设我们有一个咖啡店,我们需要在不改变原有咖啡的基础上,为顾客提供添加调料的服务。我们首先定义一个咖啡接口(Component),它定义了咖啡的基本行为:

代码语言:javascript复制
public interface Coffee {
    String getDescription();
    double getCost();
}

然后,我们实现一个具体的咖啡类(ConcreteComponent),它实现了咖啡接口,并提供了基本的咖啡信息:

代码语言:javascript复制
public class SimpleCoffee implements Coffee {
    @Override
    public String getDescription() {
        return "Simple Coffee";
    }

    @Override
    public double getCost() {
        return 1.0;
    }
}

接下来,我们定义一个装饰者抽象类(Decorator),它也实现了咖啡接口,但是它不直接提供咖啡服务,而是将服务委托给其它的组件。我们需要注意的是,装饰者类中需要保留一个对原有组件的引用。

代码语言:javascript复制
public abstract class CoffeeDecorator implements Coffee {
    protected Coffee coffee;

    public CoffeeDecorator(Coffee coffee) {
        this.coffee = coffee;
    }

    @Override
    public String getDescription() {
        return coffee.getDescription();
    }

    @Override
    public double getCost() {
        return coffee.getCost();
    }
}

现在,我们可以定义具体的装饰者类,例如加牛奶、加糖等:

代码语言:javascript复制
public class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return coffee.getDescription()   ", Milk";
    }

    @Override
    public double getCost() {
        return coffee.getCost()   0.5;
    }
}

public class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return coffee.getDescription()   ", Sugar";
    }

    @Override
    public double getCost() {
        return coffee.getCost()   0.3;
    }
}

最后,我们可以通过如下方式来使用装饰者模式:

代码语言:javascript复制
public class Main {
    public static void main(String[] args) {
        Coffee coffee = new SimpleCoffee();
        System.out.println(coffee.getDescription()   " $"   coffee.getCost());

        coffee = new MilkDecorator(coffee);
        System.out.println(coffee.getDescription()   " $"   coffee.getCost());

        coffee = new SugarDecorator(coffee);
        System.out.println(coffee.getDescription()   " $"   coffee.getCost());
    }
}

在这个例子中,我们首先创建了一个简单咖啡对象,然后依次为其添加牛奶和糖装饰器。每次添加装饰器都会修改咖啡的描述和价格,但是并没有改变原有咖啡对象的结构。

输出结果如下:

代码语言:javascript复制
Simple Coffee $1.0
Simple Coffee, Milk $1.5
Simple Coffee, Milk, Sugar $1.8

可以看到,我们通过装饰者模式,成功地为咖啡店提供了添加调料的服务,而且这个服务可以根据需要随意扩展。

0 人点赞