裝飾者模式

裝飾者模式:動態將責任附加到對象上。若要擴展功能,裝飾者提供了比集成更有彈性的替代方案。編程

原則:封裝變化;多用組合,少用繼承;針對接口編程,不針對實現編程;爲交互對象之間的鬆耦合設計而努力;對擴展開放,對修改關閉。ide

Beverage是抽象基類,是被裝飾者,getDescription()有基本實現,子類可重寫,cost()是抽象方法,子類必須重寫。HouseBlend,DarkRoast,Espresso,Decaf是具體的被裝飾者,只須要擴展實現基類中的cost()方法。CondimentDecorator是裝飾者抽象基類,繼承自Beverage,下面的四個是具體的裝飾者子類。擴展實現cost()和getDescription()方法,cost()須要將本身的花費加上。測試

Beverage抽象基類被裝飾者:this

1 public abstract class Beverage {
2 
3     String description = "Unknown Beverage";
4     
5     public String getDescription() {
6         return description;
7     }
8     public abstract double cost();
9 }
View Code

CondimentDecorator抽象基類裝飾者:spa

1 public abstract class CondimentDecorator extends Beverage{
2     public abstract String getDescription();
3 }
View Code

DarkRoast具體被裝飾者子類:設計

 1 public class DarkRoast extends Beverage {
 2 
 3     public DarkRoast() {
 4         description = "DarkRoast";
 5     }
 6     public double cost() {
 7         return 0.99;
 8     }
 9 
10 }
View Code

Mocha具體裝飾者子類:code

 1 public class Mocha extends CondimentDecorator{
 2     Beverage beverage;
 3     
 4     public Mocha(Beverage beverage) {
 5         this.beverage = beverage;
 6     }
 7     public String getDescription() {
 8         System.out.println("mochaDescription");
 9         return beverage.getDescription() + ",Mocha";
10     }
11     public double cost() {
12         System.out.println("mochaCost");
13         return 0.20 + beverage.cost();
14     }
15 }
View Code

Whip具體裝飾者子類:對象

 1 public class Whip extends CondimentDecorator{
 2     Beverage beverage;
 3     
 4     public Whip(Beverage beverage) {
 5         this.beverage = beverage;
 6     }
 7     public String getDescription() {
 8         System.out.println("whipDescription");
 9         return beverage.getDescription() + ",Whip";
10     }
11     public double cost() {
12         System.out.println("whipCost");
13         return 0.10 + beverage.cost();
14     }
15 }
View Code

測試類:blog

 1 public class StarbuzzCoffee {
 2 
 3     public static void main(String[] args) {
 4         Beverage beverage = new Espresso();
 5         System.out.println(beverage.getDescription() + "$" + beverage.cost());
 6         Beverage beverage2 = new DarkRoast();
 7         beverage2 = new Mocha(beverage2);
 8         beverage2 = new Mocha(beverage2);
 9         beverage2 = new Whip(beverage2);
10         System.out.println(beverage2.getDescription() + "$" + beverage2.cost());
11     }
12 
13 }
View Code

 

 

1.裝飾者和被裝飾者對象具備相同的超類型,因此在任何使用被裝飾者對象的場合,能夠用裝飾過的對象來代替它。(因此裝飾者類反映出被裝飾的組件的類型)繼承

2.裝飾者不只能夠裝飾具體構件,還能夠裝飾裝飾者

3.裝飾者和被裝飾者都繼承(或實現)自相同的超類型(Component),咱們是利用繼承達到「類型匹配」,而不是利用繼承得到「行爲」。當咱們將裝飾者與組件(或裝飾者)組合時,加入的新的行爲並非繼承自超類,而是由組合對象(ConcreteComponent或ConcreteDecorator)得來的。

4.雖然裝飾者模式能夠爲設計注入彈性,但裝飾者也經常形成設計中有大量的小對象,若是過分使用會讓程序變得很複雜。

5.裝飾模式VS繼承:裝飾模式是使用組合和委託用來擴展特定對象的功能,不須要子類,動態地在運行時給對象加上新的行爲,防止了因爲子類而致使的複雜和混亂,具備更多的靈活性。而繼承是用來擴展一類對象的功能,須要子類,靜態地在編譯時分派職責,致使了不少子類的產生,缺少靈活性。

6.裝飾者通常對組件的客戶是透明的,除非客戶程序依賴於組件的具體類型

7.Decorator裝飾者角色並非必須的,當你僅須要添加一個職責時,沒有必要定義抽象Decorator類。你經常須要處理現存的類層次結構而不是設計一個新系統,這時你能夠把Decorator向Component轉發請求的職責合併到Concrete Decorator中。

8.改變對象外殼與改變對象內核:咱們能夠將Decorator看做一個對象的外殼,它能夠改變這個對象的行爲。另一種方法是改變對象的內核。例如, Strategy(策略)模式就是一個用於改變內核的很好的模式。

 

I/O應用:

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息