设计模式---装饰模式
故事:穿什么有這么重要?
定義:
裝飾模式:動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé),就增加功能來(lái)說(shuō),裝飾模式比生成子類更為靈活。
但是純粹的裝飾模式很難找到,大多數(shù)的裝飾模式的實(shí)現(xiàn)都是“半透明”的,而不是完全透明的。換言之,允許裝飾模式改變接口,增加新的方法。半透明的裝飾模式是介于裝飾模式和適配器模式之間的。適配器模式的用意是改變所考慮的類的接口,也可以通過(guò)改寫(xiě)一個(gè)或幾個(gè)方法,或增加新的方法來(lái)增強(qiáng)或改變所考慮的類的功能。
大多數(shù)的裝飾模式實(shí)際上是半透明的裝飾模式,這樣的裝飾模式也稱做半裝飾、半適配器模式。
Component 是定義一個(gè)對(duì)象接口,可以給這些對(duì)象動(dòng)態(tài)的添加職責(zé)。ConcreteComponent是定義一個(gè)具體的對(duì)象,也可以給這個(gè)對(duì)象添加一些職責(zé)。Decorator,裝飾抽象類,繼承了component,從外類來(lái)擴(kuò)展component類的功能,但對(duì)于Component來(lái)說(shuō),是無(wú)需知道Decorator的存在的。至于ConcreteDecorator就是具體的裝飾對(duì)象,起到給Component添加職責(zé)的功能。
針對(duì)的問(wèn)題:
? ? ? ? 動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)。就增加功能來(lái)說(shuō),Decorator模式相比生成子類更為靈活。不改變接口的前提下,增強(qiáng)所考慮的類的性能。
何時(shí)使用:
? ? 1)需要擴(kuò)展一個(gè)類的功能,或給一個(gè)類增加附加責(zé)任。
? ? 2)需要?jiǎng)討B(tài)的給一個(gè)對(duì)象增加功能,這些功能可以再動(dòng)態(tài)地撤銷(xiāo)。
? ? 3)需要增加一些基本功能的排列組合而產(chǎn)生的非常大量的功能,從而使繼承變得????不現(xiàn)實(shí)。
實(shí)例:
咖啡是一種飲料,咖啡的本質(zhì)是咖啡豆+水磨出來(lái)的??Х鹊戡F(xiàn)在要賣(mài)各種口味的咖啡,如果不使用裝飾模式,那么在銷(xiāo)售系統(tǒng)中,各種不一樣的咖啡都要產(chǎn)生一個(gè)類,如果有4中咖啡豆,5種口味,那么將要產(chǎn)生至少20個(gè)類(不包括混合口味),非常麻煩。使用了裝飾模式,只需要11個(gè)類即可生產(chǎn)任意口味咖啡(包括混合口味)。
??
Beverage飲料接口
/** * 飲料接口 * @author Administrator * */ public interface Beverage { //返回商品描述 public String getDescription(); //返回價(jià)格 public double getPrice(); }
CoffeeBean1——具體被裝飾的對(duì)象類1
public class CoffeeBean1 implements Beverage { private String description = "選了第一種咖啡豆"; @Override public String getDescription() { return description; } @Override public double getPrice() { return 50; } }CoffeeBean2——具體被裝飾的對(duì)象類2
public class CoffeeBean2 implements Beverage { private String description = "第二種咖啡豆!"; @Override public String getDescription() { return description; } @Override public double getPrice() { return 100; } }Decorator——裝飾類
public class Decorator implements Beverage { private String description = "我只是裝飾器,不知道具體的描述"; @Override public String getDescription() { return description; } @Override public double getPrice() { return 0; //價(jià)格由子類來(lái)決定 } }
Milk——具體裝飾類,給咖啡加入牛奶
public class Milk extends Decorator{ private String description = "加了牛奶!"; private Beverage beverage = null; public Milk(Beverage beverage){ this.beverage = beverage; } public String getDescription(){ return beverage.getDescription()+"\n"+description; } public double getPrice(){ return beverage.getPrice()+20; //20表示牛奶的價(jià)格 } }
Mocha——給咖啡加入摩卡
public class Mocha extends Decorator { private String description = "加了摩卡!"; private Beverage beverage = null; public Mocha(Beverage beverage){ this.beverage = beverage; } public String getDescription(){ return beverage.getDescription()+"\n"+description; } public double getPrice(){ return beverage.getPrice()+49; //30表示摩卡的價(jià)格 } }
Soy——給咖啡加入豆?jié){
public class Soy extends Decorator { private String description = "加了豆?jié){!"; private Beverage beverage = null; public Soy(Beverage beverage){ this.beverage = beverage; } public String getDescription(){ return beverage.getDescription()+"\n"+description; } public double getPrice(){ return beverage.getPrice()+30; //30表示豆?jié){的價(jià)格 } }測(cè)試類:
public class Test { public static void main(String[] args) { Beverage beverage = new CoffeeBean1(); //選擇了第一種咖啡豆磨制的咖啡 beverage = new Mocha(beverage); //為咖啡加了摩卡 beverage = new Milk(beverage); System.out.println(beverage.getDescription()+"\n加了摩卡和牛奶的咖啡價(jià)格:"+beverage.getPrice()); } }
測(cè)試結(jié)果:
裝飾模式和適配器模式的關(guān)系:
裝飾模式和適配器模式都是“包裝模式(Wrapper?Pattern)”,它們都是通過(guò)封裝其他對(duì)象達(dá)到設(shè)計(jì)的目的的,但是它們的形態(tài)有很大區(qū)別。
理想的裝飾模式在對(duì)被裝飾對(duì)象進(jìn)行功能增強(qiáng)的同時(shí),要求具體構(gòu)件角色、裝飾角色的接口與抽象構(gòu)件角色的接口完全一致。而適配器模式則不然,一般而言,適配器模式并不要求對(duì)源對(duì)象的功能進(jìn)行增強(qiáng),但是會(huì)改變?cè)磳?duì)象的接口,以便和目標(biāo)接口相符合。
裝飾模式有透明和半透明兩種,這兩種的區(qū)別就在于裝飾角色的接口與抽象構(gòu)件角色的接口是否完全一致。透明的裝飾模式也就是理想的裝飾模式,要求具體構(gòu)件角色、裝飾角色的接口與抽象構(gòu)件角色的接口完全一致。相反,如果裝飾角色的接口與抽象構(gòu)件角色接口不一致,也就是說(shuō)裝飾角色的接口比抽象構(gòu)件角色的接口寬的話,裝飾角色實(shí)際上已經(jīng)成了一個(gè)適配器角色,這種裝飾模式也是可以接受的,稱為“半透明”的裝飾模式,如下圖所示。
?
?在適配器模式里面,適配器類的接口通常會(huì)與目標(biāo)類的接口重疊,但往往并不完全相同。換言之,適配器類的接口會(huì)比被裝飾的目標(biāo)類接口寬。
顯然,半透明的裝飾模式實(shí)際上就是處于適配器模式與裝飾模式之間的灰色地帶。如果將裝飾模式與適配器模式合并成為一個(gè)“包裝模式”的話,那么半透明的裝飾模式倒可以成為這種合并后的“包裝模式”的代表。
優(yōu)點(diǎn):
(1)裝飾模式與繼承關(guān)系的目的都是要擴(kuò)展對(duì)象的功能,但是裝飾模式可以提供比繼承更多的靈活性。裝飾模式允許系統(tǒng)動(dòng)態(tài)決定“貼上”一個(gè)需要的“裝飾”,或者除掉一個(gè)不需要的“裝飾”。繼承關(guān)系則不同,繼承關(guān)系是靜態(tài)的,它在系統(tǒng)運(yùn)行前就決定了。
(2)通過(guò)使用不同的具體裝飾類以及這些裝飾類的排列組合,設(shè)計(jì)師可以創(chuàng)造出很多不同行為的組合。
缺點(diǎn):
使用裝飾模式會(huì)產(chǎn)生比使用繼承關(guān)系更多的對(duì)象。更多的對(duì)象會(huì)使得查錯(cuò)變得困難,特別是這些對(duì)象看上去都很相像。
轉(zhuǎn)載于:https://www.cnblogs.com/zhanghu52030/p/7912345.html
總結(jié)
以上是生活随笔為你收集整理的设计模式---装饰模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: day08 MapReduce
- 下一篇: WPF控件截图