設計模式-裝飾者模式(Decorator)
阿新 • • 發佈:2018-11-24
概述
- 定義 : 在不改變原有物件的基礎之上, 將功能附加到物件上
- 提供了比繼承更有彈性的替代方案(擴充套件原有物件功能)
- 又叫包裝器Wrapper, 介面卡模式也被稱之為包裝器
- 型別 : 結構型
適用場景
- 擴充套件一個類的功能或給一個類新增附加職責
- 動態的給一個物件新增功能, 這些功能可以再動態的撤銷
優點
- 繼承放入有力補充, 比繼承靈活, 在不改變原有物件的情況下給一個物件擴充套件功能
- 通過使用不同裝飾類以及這些裝飾類的排列組合, 可以實現不同效果
缺點
- 會出現更多的程式碼, 更多的類, 增加程式複雜性
- 動態裝飾時, 多層裝飾時更復雜
模式角色
-
Component : 定義一個物件介面,可以給這些物件動態地新增職責
-
ConcreteComponent : 定義一個物件,可以給這個物件新增一些職責
-
Decorator : 維持一個指向Component物件的引用,並定義一個與Component介面一致的介面, Java中通常是使用構造器接收Component, Java中通常裝飾者類和被裝飾的類實現同樣的介面, 所以這個角色大多數時候就使用Component介面
-
ConcreteDecorator : 向元件新增職責, Java中代表包裝類
程式碼實現
業務場景
有一個coffee介面, 有一個實現類coffee, 如果需要加一份牛奶的話, 就呼叫牛奶裝飾器, 如果需要加糖的話, 就呼叫加糖的裝飾器, 最終可以展示coffee中加了哪些東西, 加完之後的價格是多少
UML類圖
程式碼實現
Icoffee介面:
/**
* 被裝飾的類介面
* 這裡也可以使用抽象類實現
* @author 七夜雪
* @create 2018-11-23 14:40
*/
public interface ICoffee {
public void showDesc();
public String getDesc ();
public int getPrice();
}
Coffee類:
/**
* 普通的Coffee類
*
* @author 七夜雪
* @create 2018-11-23 14:41
*/
public class Coffee implements ICoffee {
private String desc = "一杯咖啡";
private int price = 20;
@Override
public void showDesc() {
System.out.println(desc + " 價格為:" + price);
}
@Override
public String getDesc() {
return desc;
}
@Override
public int getPrice() {
return price;
}
}
牛奶包裝類:
/**
* 牛奶裝飾類 : 表示向咖啡中加一份牛奶
*
* @author 七夜雪
* @create 2018-11-23 14:44
*/
public class MilkDecorator implements ICoffee {
private String desc;
private int price;
public MilkDecorator(ICoffee coffee) {
this.desc = coffee.getDesc() + " 加一份牛奶";
// 表示每加一份牛奶, 價格增加3元
this.price = coffee.getPrice() + 3;
}
@Override
public void showDesc() {
System.out.println(desc + " 價格為:" + price);
}
@Override
public int getPrice() {
return price;
}
@Override
public String getDesc() {
return desc;
}
}
糖包裝類:
/**
* 糖裝飾類 : 表示向咖啡中加一份糖
*
* @author 七夜雪
* @create 2018-11-23 14:44
*/
public class SugarDecorator implements ICoffee {
private String desc;
private int price;
public SugarDecorator(ICoffee coffee) {
this.desc = coffee.getDesc() + " 加一份糖";
// 表示每加一份牛奶, 價格增加2元
this.price = coffee.getPrice() + 2;
}
@Override
public void showDesc() {
System.out.println(desc + " 價格為:" + price);
}
@Override
public int getPrice() {
return price;
}
@Override
public String getDesc() {
return desc;
}
}
測試程式碼:
public static void main(String[] args) {
ICoffee coffee = new Coffee();
coffee = new MilkDecorator(coffee);
coffee = new SugarDecorator(coffee);
coffee = new SugarDecorator(coffee);
coffee.showDesc();
}
測試結果:
一杯咖啡 加一份牛奶 加一份糖 加一份糖 價格為:27