這篇博客主要是總結一下java中的裝飾者設計模式。
1.繼承帶來的問題
舉一個生活中常見的例子來說明繼承帶來的問題。豆漿,大家一定不陌生。有純豆漿,加糖豆漿,黑豆豆漿,紅棗豆漿,綠豆豆漿等等,如果我們要寫一個程序來計算每種豆漿的價格以及說明這種豆漿的配料,如果按照之前的學習的,我們將會繼承一個豆漿類,然后在其之上,重寫自己的方法,但是對于豆漿來說,種類實在太多了,我們就要寫很多很多的子類,這樣的話便會引起類爆炸,于是,便產生的裝飾者這種設計模式。
2.裝飾者模式概述 涉及角色: 抽象構件角色:定義一個抽象接口,來規范準備附加功能的類 具體構件角色:將要被附加功能的類,實現抽象構件角色接口 抽象裝飾者角色:持有對具體構件角色的引用并定義與抽象構件角色一致的接口 具體裝飾角色:實現抽象裝飾者角色,負責為具體構件添加額外功能
3.裝飾者模式實現 我們就以豆漿的例子為例,來實現一下裝飾者模式
抽象構件角色,來規范準備附加功能的類
/** * 被裝飾者對象的接口 */public interface Drink { //飲料的描述信息 public String description(); //計算價格 public float cost();}具體的構建角色,將要被附加功能的類
** * 具體的被裝飾者的對象 */public class SoyaBeanMilk implements Drink{ @Override public String description() { return "純豆漿"; } @Override public float cost() { return 5f; }}抽象裝飾者角色:持有對具體構件角色的引用并定義與抽象構件角色一致的接口
/** * 裝飾者基類 */public abstract class Decorator implements Drink{ //要裝飾的對象 PRivate Drink drink;//關聯Drink //使用構造方法初始化關聯的類對象,很經典 public Decorator(Drink drink) { this.drink=drink; } @Override public String description() { return drink.description(); } @Override public float cost() { return drink.cost(); }}** *具體的裝飾者對象:糖 */public class SugarDecorator extends Decorator{ public SugarDecorator(Drink drink) { super(drink); } @Override public String description() { return super.description()+"+糖"; } @Override public float cost() { return super.cost()+0.5f; }}/** * 具體的裝飾者對象--黑豆 */public class BlackBeanDecorator extends Decorator { public BlackBeanDecorator(Drink drink) { super(drink); } @Override public String description() { return super.description()+"+黑豆"; } @Override public float cost() { return super.cost()+3.0f; }}/** * 具體的裝飾者對象:雞蛋 */public class EggDecorator extends Decorator {public EggDecorator(Drink drink){ super(drink);} @Override public String description() { return super.description()+"+雞蛋"; } @Override public float cost() { return super.cost()+2.0f; }}/***測試類*/public class Test { public static void main(String args[]) { //生產一杯豆漿 Drink soya = new SoyaBeanMilk(); //在豆漿中加雞蛋 EggDecorator eggsoya=new EggDecorator(soya); //在雞蛋豆漿中加糖 SugarDecorator sugarEggSoya=new SugarDecorator(eggsoya); //在加了糖的豆漿中加黑豆 BlackBeanDecorator blackBeanSugarEggSoya=new BlackBeanDecorator(sugarEggSoya); //結賬 System.out.println("同志,您點的是:"+blackBeanSugarEggSoya.description()); System.out.println("您一共消費了"+blackBeanSugarEggSoya.cost()); }}4.裝飾者模式小結 OO原則:動態地將責任附加對象上。 想要拓展功能,裝飾者提供有別于繼承的另一種選擇
要點: (1)繼承屬于拓展形式之一,但不見得是達到彈性設計的最佳方法 (2)在我們的設計中,應該允許行為可以被拓展,而不須修改現有的代碼 (3)組合和委托可用于在運行時動態地加上新行為 (4)除了繼承,裝飾者模式也可以讓我們拓展行為 (5)裝飾者模式意味著一群裝飾者類,這些類用來包裝具體組件 (6)裝飾者類反應出被裝飾的組件的類型(實際上,他們具有相同的類型,都經過接口或者繼承實現) (7)裝飾者可以在被裝飾者的行為前面或者后面加上自己的行為,甚至將被裝飾者的行為整個取代掉,而得到特定的目的 (8)你可以有無數個裝飾者包裝的一個組件 (9)裝飾者一般對組件的客戶是透明的,除非客戶程序依賴于組件的具體類型
新聞熱點
疑難解答