在公司上班,經過大半天的忙碌,每到下午三四點,肚子就感覺咕咕叫,嘴巴也挺寂寞的,於是乎就想着點杯奶茶慰勞下自己。喝過奶茶的小伙伴都知道,點奶茶加點配料更爽口,例如燕麥(oats),珍珠(pearl),布丁(pudding)等等,當然了,每種配料的價格都是不一樣的,那么我們今天要做的就是,不管你是點奶茶,還是咖啡,還是鮮果茶;不管你在茶里面加布丁、還是珍珠,最終需要展示價格是奶茶基礎價加上每一種所選配料價格的總和。例如:奶茶加燕麥,加珍珠,加布丁,銷售價格:12.0
規格表如下:
1、下面我們先看代碼,再總結:
/** * Created by sww_6 on 2019/4/25. * 被裝飾對象的基類 */ public abstract class Tea { public abstract String desc(); public abstract double price(); }
/** * Created by sww_6 on 2019/4/25. * 具體被裝飾對象,奶茶基類。 */ public class MilkTea extends Tea { public String desc() { return "奶茶"; } public double price() { return 8; } }
/** * Created by sww_6 on 2019/4/25. * 具體被裝飾對象,咖啡基類。 */ public class Coffee extends Tea { public String desc() { return "拿鐵"; } public double price() { return 10; } }
/** * Created by sww_6 on 2019/4/25. * 配料裝飾者 */ public class DosingDecorator extends Tea { private Tea tea; public DosingDecorator(Tea tea) { this.tea = tea; } public String desc() { return tea.desc(); } public double price() { return tea.price(); } }
/** * Created by sww_6 on 2019/4/25. * 配料具體裝飾者,燕麥。 */ public class Oats extends DosingDecorator { public Oats(Tea tea) { super(tea); } @Override public String desc() { return super.desc() + "加燕麥,"; } @Override public double price() { return super.price() + 1; } }
/** * Created by sww_6 on 2019/4/25. * 配料具體裝飾者,珍珠。 */ public class Pearl extends DosingDecorator { public Pearl(Tea tea) { super(tea); } @Override public String desc() { return super.desc() + "加珍珠,"; } @Override public double price() { return super.price() + 1; } }
/** * Created by sww_6 on 2019/4/25. * 配料具體裝飾者,布丁。 */ public class Pudding extends DosingDecorator { public Pudding(Tea tea) { super(tea); } @Override public String desc() { return super.desc() + "加布丁,"; } @Override public double price() { return super.price() + 2; } }
下面就是測試類。
/** * Created by sww_6 on 2019/4/25. * 測試類,測試奶茶和咖啡。 */ public class Test { public static void main(String[] args) { Tea tea; tea = new Coffee(); System.out.println(tea.desc()+"銷售價格:"+tea.price()); tea = new MilkTea(); tea = new Oats(tea); tea = new Pearl(tea); tea = new Pudding(tea); System.out.println(tea.desc() + "銷售價格:"+tea.price()); } }
測試結果如下:
拿鐵銷售價格:10.0
奶茶加燕麥,加珍珠,加布丁,銷售價格:12.0
2、類圖
大家看,這個類圖是不是一目了然呢?
3、參與者
1.Component(被裝飾對象的基類),即tea抽象類。
定義一個對象接口,可以給這些對象動態地添加職責。
2.ConcreteComponent(具體被裝飾對象),即Coffee和MilkTea類。
定義一個對象,可以給這個對象添加一些職責。
3.Decorator(裝飾者抽象類),即DosingDecorator(配料裝飾者)類。
維持一個指向Component實例的引用,並定義一個與Component接口一致的接口。
4.ConcreteDecorator(具體裝飾者),即珍珠(Pearl),燕麥(Oats),布丁(Pudding)類。
具體的裝飾對象,給內部持有的具體被裝飾對象,增加具體的職責。
4、涉及角色
(1)抽象組件:定義一個抽象接口,來規范准備附加功能的類
(2)具體組件:將要被附加功能的類,實現抽象構件角色接口
(3)抽象裝飾者:持有對具體構件角色的引用並定義與抽象構件角色一致的接口
(4)具體裝飾:實現抽象裝飾者角色,負責對具體構件添加額外功能。
5、意圖:
動態地給一個對象添加一些額外的職責。就增加功能來說, Decorator模式相比生成子類更為靈活。該模式以對客 戶端透明的方式擴展對象的功能。