设计模式-装饰模式

一 装饰模式:

      装饰模式(Decorator Pattern)是结构型的设计模式,它允许在运行时动态地向对象添加新的职责或功能,同时保持对象的原始类不变。通过使用装饰器模式,可以在不修改现有代码的基础上扩展对象的功能,遵循了开闭原则(Open-Closed Principle, OCP),对扩展开放和对修改封闭。

角色和结构:

1 Component(抽象构件)

  • 定义一个接口以规范对象的行为。
  • 通常是一个抽象类,包含具体组件和装饰者都必须实现的接口方法。

2 ConcreteComponent(具体构件)

  • 实现了Component接口的具体对象,它是需要被装饰的对象。

3 Decorator(装饰器)

  • 继承自Component接口或者实现Component接口,并且持有Component对象的一个引用。
  • 装饰器可以是抽象类或接口,定义与Component一致的方法以便在运行时“代理”其行为。

4 ConcreteDecorator(具体装饰器)

  • 具体装饰器类,继承自Decorator并实现了Component接口的所有方法。
  • 在实现方法时,除了调用被装饰对象相应的方法之外,还可以在调用前后增加额外的操作来增强或改变原有行为。

工作原理:

  • 当客户程序需要为某个对象添加新的功能时,不修改该对象,要将对象封装在一个装饰器中。
  • 装饰器对象在内部持有一个指向真实对象的引用,并在实现Component接口方法时选择性地调用真实对象的方法,或者在调用前后附加自己的行为。

示例代码:

装饰模式示例代码如下:

// 抽象构件
public abstract class Coffee {
    public abstract double getCost();
    public abstract String getDescription();
}

// 具体构件
public class SimpleCoffee extends Coffee {
    @Override
    public double getCost() {
        return 1.0;
    }

    @Override
    public String getDescription() {
        return "Simple Coffee";
    }
}

// 装饰器抽象类
public abstract class CoffeeDecorator extends Coffee {
    protected Coffee coffee;

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

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

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

// 具体装饰器
public class MilkCoffeeDecorator extends CoffeeDecorator {
    public MilkCoffeeDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public double getCost() {
        return super.getCost() + 0.5; // 添加牛奶的价格
    }

    @Override
    public String getDescription() {
        return super.getDescription() + ", with Milk"; // 描述中增加牛奶信息
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Coffee simpleCoffee = new SimpleCoffee();
        System.out.println("Cost: " + simpleCoffee.getCost());
        System.out.println("Description: " + simpleCoffee.getDescription());

        Coffee milkCoffee = new MilkCoffeeDecorator(simpleCoffee);
        System.out.println("\nCost after adding milk: " + milkCoffee.getCost());
        System.out.println("Description after adding milk: " + milkCoffee.getDescription());
    }
}

 说明:上面的代码,Coffee 是抽象构件,SimpleCoffee 是具体构件。CoffeeDecorator 是装饰器抽象类,而 MilkCoffeeDecorator 是具体的装饰器类,它给咖啡增加了加奶的功能,并且相应地调整了成本和描述。通过这样的设计,我们可以很容易地添加其他类型的装饰器(例如糖、香草等),从而扩展咖啡的不同口味和价格。

优点:

  • 动态地给对象添加功能,相比生成子类更加灵活、透明。
  • 无需修改原有类就可以扩展功能,符合开闭原则。
  • 装饰器可以被组合,以便在运行时动态地、多次地添加多个职责。

应用场景:

  • 当需要为单个对象提供多种不同的行为或者表现形式时。
  • 需要向一个已经存在的类中添加功能,但又不希望修改该类的源代码或继承其子类时。

你可能感兴趣的:(设计模式)