1.裝飾器模式介紹
裝飾器模式是一種結構型設計模式,允許你動態地給對象添加行為,而無需修改其代碼。它的核心思想是將對象放入一個“包裝器”中,這個包裝器提供了額外的功能,同時保持原有對象的接口不變。
想象一下,你有一個簡單的咖啡,你想讓它變得更特別。你可以給它加奶、加糖、加香草等等,但咖啡本身還是咖啡。這些額外的東西不會改變咖啡的本質,只是讓它更豐富。
裝飾器模式有四個角色:
- 抽象組件(Component):可以是一個接口或者抽象類,規定了被裝飾對象的行為;
- 具體組件(ConcreteComponent):實現或繼承Component的一個具體對象,也即被裝飾對象;
- 抽象裝飾器(Decorator):一般是抽象類, 繼承或實現抽象組件Component;其內部必然有一個屬性指向Component組件對象;通過其子類 ConcreteDecorator 擴展具體構件的功能。
- 具體裝飾器(ConcreteDecorator):Decorator的具體實現類,理論上每個ConcreteDecorator 都擴展了 Component 對象的一種功能;
四個角色的關系:
2.代碼演示
抽象組件(Component):咖啡接口定義了咖啡有“描述”和“價格”兩個方法
// 基礎接口
interface Coffee {String getDescription();double getCost();
}
具體組件(ConcreteComponent): 咖啡實現類,是需要被裝飾的對象
// 具體的咖啡類
class SimpleCoffee implements Coffee {@Overridepublic String getDescription() {return "Simple Coffee";}@Overridepublic double getCost() {return 5.0;}
}
抽象裝飾器(Decorator):抽象類,實現咖啡接口,內部有一個屬性指向Coffee對象
// 裝飾器基類
abstract class CoffeeDecorator implements Coffee {//內部必然有一個屬性指向Component組件對象protected Coffee coffee;public CoffeeDecorator(Coffee coffee) {this.coffee = coffee;}@Overridepublic String getDescription() {return coffee.getDescription();}@Overridepublic double getCost() {return coffee.getCost();}
}
具體裝飾器(ConcreteDecorator):每個Coffee裝飾器都擴展了Coffee對象的一種功能
// 具體的裝飾器類
class MilkDecorator extends CoffeeDecorator {public MilkDecorator(Coffee coffee) {super(coffee);}@Overridepublic String getDescription() {return coffee.getDescription() + ", Milk";}@Overridepublic double getCost() {return coffee.getCost() + 1.5;}
}class SugarDecorator extends CoffeeDecorator {public SugarDecorator(Coffee coffee) {super(coffee);}@Overridepublic String getDescription() {return coffee.getDescription() + ", Sugar";}@Overridepublic double getCost() {return coffee.getCost() + 0.5;}
}
使用裝飾器:每個裝飾器都可以單獨或組合使用,給咖啡增加不同的特性。通過這種方式,原來的咖啡類保持不變,而我們可以靈活地為它添加新功能
// 使用裝飾器模式
public class CoffeeShop {public static void main(String[] args) {//創建簡單的咖啡類SimpleCoffeeCoffee coffee = new SimpleCoffee();System.out.println(coffee.getDescription() + " $" + coffee.getCost());//通過裝飾器MilkDecorator給咖啡加奶coffee = new MilkDecorator(coffee);System.out.println(coffee.getDescription() + " $" + coffee.getCost());//通過裝飾器SugarDecorator給咖啡加糖coffee = new SugarDecorator(coffee);System.out.println(coffee.getDescription() + " $" + coffee.getCost());}
}