裝飾者模式
為什么要使用裝飾者模式
舉個栗子:
老王是一個豆漿店的老板,因為豆漿品種多,生意火爆,我看著老王賺錢比較眼饞,晚上和他套近乎喝了點啤酒,老王就把配方分享給我了,具體配方如下:
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-4naZjvt8-1610692365503)(%E8%A3%85%E9%A5%B0%E8%80%85%E6%A8%A1%E5%BC%8F.assets/image-20210115131504657.png)]](https://img.uj5u.com/2021/01/16/215915161207541.png)
如果此時由于生意火爆,老王又加了一種輔料:西瓜
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ouMQvRnc-1610692365505)(%E8%A3%85%E9%A5%B0%E8%80%85%E6%A8%A1%E5%BC%8F.assets/image-20210115131600619.png)]](https://img.uj5u.com/2021/01/16/215915161207542.png)
類似于在開發中子類與父類的關系,子類功能比父類強大,但是由于子類數量增加,會形成類爆炸現象
如果實作子類繼承父類,那么我們要寫很多子類,這樣做無疑增加了程式的臃腫性,并不是很靈活,這時,裝飾者模式就可以幫助我們使得程式變得更簡潔
裝飾者的概念
裝飾者模式又名包裝模式,動態的給一個物件添加一些額外的職責,就擴展功能而言,它比生成子類的方式更加靈活
適用場景:
- 以動態的方式給物件添加職責
- 處理那些可以撤銷的職責
- 當采用生成子類的方法來進行擴充時,可能有大量獨立的擴展,為支持每一種組合將產生大量的子類,使得子類數量呈現爆炸性增長
裝飾者模式的結構
抽象組件(Component):給出一個抽象介面,以規范準備接受附加責任的物件
被裝飾者(ConcreteComponent):Component的具體實作,也就是我們要裝飾的具體的物件
裝飾者組件(Decorator):持有組件(Component)物件的實體參考,該類的職責就是為了 裝飾具體組件的物件,定義的基類
具體裝飾(ConcreteDecorator):負責給構件物件裝飾附加的功能
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-NszLrJow-1610692365509)(%E8%A3%85%E9%A5%B0%E8%80%85%E6%A8%A1%E5%BC%8F.assets/5e9d18e300010cd419201080.jpg)]](https://img.uj5u.com/2021/01/16/215915161207543.jpg)
遷移到豆漿案例則具體職責如下:
![[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-xEbOrOST-1610692365512)(%E8%A3%85%E9%A5%B0%E8%80%85%E6%A8%A1%E5%BC%8F.assets/image-20210115133120985.png)]](https://img.uj5u.com/2021/01/16/215915161207544.png)
一個小Demo
飲品介面(Component):
package cn.homyit.designpattern.decorator;
/**
* Component
* 抽象組件
* 飲品介面
*/
public interface Drink {
//價格
double price();
//品種描述
String description();
}
飲品實作類豆漿(ConcreteComponent)
package cn.homyit.designpattern.decorator;
/**
* ConcreteComponent
* 被裝飾者
* 豆漿
*/
public class Soya implements Drink{
@Override
public double price() {
return 5;
}
@Override
public String description() {
return "純豆漿";
}
}
裝飾者(Decorator)
package cn.homyit.designpattern.decorator;
/**
* Decorator
* 裝飾器組件
* 1.抽象類
* 2.實作抽象組件介面
* 3.持有抽象介面的參考
*/
public abstract class Decorator implements Drink{
//定義私有飲品參考
private Drink drink;
//通過構造來創建抽象介面的參考
public Decorator(Drink drink){
this.drink = drink;
}
@Override
public double price() {
return drink.price();
}
@Override
public String description() {
return drink.description();
}
}
具體裝飾即各種豆漿(ConcreteDecorator)
package cn.homyit.designpattern.decorator;
/**
* ConcreteDecorator
* 具體裝飾
* 紅豆豆漿
*/
public class RedBeanSoya extends Decorator{
public RedBeanSoya(Drink drink) {
super(drink);
}
//重寫價格
@Override
public double price() {
return super.price()+3.2;
}
//重寫描述
@Override
public String description() {
return super.description()+"+紅豆";
}
}
package cn.homyit.designpattern.decorator;
/**
* ConcreteDecorator
* 具體裝飾
* 雞蛋豆漿
*/
public class EggSoya extends Decorator{
public EggSoya(Drink drink) {
super(drink);
}
//重寫價格
@Override
public double price() {
return super.price()+3.9;
}
//重寫描述
@Override
public String description() {
return super.description()+"+雞蛋";
}
}
package cn.homyit.designpattern.decorator;
/**
* ConcreteDecorator
* 具體裝飾
* 糖豆漿
*/
public class SugarSoya extends Decorator{
public SugarSoya(Drink drink) {
super(drink);
}
//重寫價格
@Override
public double price() {
return super.price()+2.1;
}
//重寫描述
@Override
public String description() {
return super.description()+"加糖";
}
}
測驗類:
package cn.homyit.designpattern.decorator;
/**
* 測驗類
*/
public class Test {
public static void main(String[] args) {
//創建豆漿物件
Drink soya = new Soya();
System.out.println(soya.price());
System.out.println(soya.description());
System.out.println("----------------------");
//創建紅豆豆漿
Drink redBean = new RedBeanSoya(soya);
System.out.println(redBean.price());
System.out.println(redBean.description());
System.out.println("----------------------");
//創建雞蛋豆漿
Drink egg = new EggSoya(soya);
System.out.println(egg.price());
System.out.println(egg.description());
System.out.println("----------------------");
//創建糖豆漿
Drink sugar = new SugarSoya(soya);
System.out.println(sugar.price());
System.out.println(sugar.description());
System.out.println("----------------------");
//創建紅豆雞蛋豆漿
Drink eggRedBean = new EggSoya(redBean);
System.out.println(eggRedBean.price());
System.out.println(eggRedBean.description());
System.out.println("----------------------");
}
}
列印結果如下:
5.0
純豆漿
----------------------
8.2
純豆漿+紅豆
----------------------
8.9
純豆漿+雞蛋
----------------------
7.1
純豆漿加糖
----------------------
12.1
純豆漿+紅豆+雞蛋
----------------------
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/249535.html
標籤:區塊鏈
上一篇:CROSS發起“Be creARTive”和“Bug Hunter”兩大活動,派發20,000USD大禮
下一篇:深入了解區塊鏈技術及其常見誤區
