設計模式 之 裝飾者(Decorator)模式


裝飾者模式(Decorator):動態地為一個對象添加一些額外的職責,若要擴展一個對象的功能,裝飾者提供了比繼承更有彈性的替代方案。

結構圖:

  • 抽象構件類(Component):給出一個抽象的接口,用以規范准備接收附加責任的對象
  • 具體構件類(ConcreteComponent):定義一個具體的准備接受附加責任的類,其必須實現Component接口。
  • 裝飾者類(Decorator):持有一個構件(Conponent)對象的實例,並定義一個和抽象構件一致的接口。
  • 具體裝飾者類(Concrete Decoratator):定義給構件對象“貼上”附加責任。

 

下面用一個實例來講解一下裝飾者模式《head first 設計模式》中的例子:比如在星巴茲咖啡館,人們需要根據自己的愛好來訂購咖啡,而具體的coffee種類假設一共用兩類:HouseBlend(混合咖啡)和darkRoast(深焙咖啡)。而另外客人也可根據的口味來添加一些其他的東西,例如:摩卡(mocha)、Milk(牛奶)。

從實例中可以分析出:抽象構件類對應的就是coffee飲品(下面的beverage類),具體構件類對應的就是HouseBlend和darkRoast;具體裝飾者類對應mocha和milk口味;至於裝飾者類這里沒有對應,主要用於具體裝飾者類的繼承。下面看具體d

源代碼:

抽象構件類(Component):

Beverage.java:

/**
 * @author haifei
 *    抽象構件類
 */
public abstract class Beverage {
    
    String description = "未知的咖啡";
    
    public String getDescription(){
        return description;
    }
    
    public abstract double cost();
}

 

具體構件類(ConcreteComponent):

DarkRoast.java:

/**
 * @author haifei
 *    具體構件類
 */
public class DarkRoast extends Beverage{

    public DarkRoast(){
        description = "深焙咖啡";
    }
    
    @Override
    public double cost() {
        return 1.0;
    }

}

 

 

HouseBlend.java:

/**
 * @author haifei
 *    具體構件類。HouseBlend代表咖啡中的一種:混合咖啡
 */
public class HouseBlend extends Beverage{

    
    
    public HouseBlend() {
        description = "混合咖啡";
    }

    @Override
    public double cost() {
        return .89;
    }

}

 

裝飾者類(Descorator):

ConimentDecorator.java:

/**
 * @author haifei
 *    抽象裝飾者類,所有的具體裝飾者都必須繼承這個類
 */
public abstract class CondimentDecorator extends Beverage{

    public abstract String getDescription();
    
}

 

具體裝飾者類(ConcreteDescorator):

Mocha.java:

public class Mocha extends CondimentDecorator{

    Beverage beverage;
    
    public Mocha(Beverage beverage){
        this.beverage = beverage;
    }
    
    @Override
    public String getDescription() {
        return beverage.getDescription() + ",摩卡";
    }

    @Override
    public double cost() {
        return beverage.cost() + .20;
    }

}

 

Milk.java:

public class Milk extends CondimentDecorator{

    Beverage beverage;
    
    public Milk(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription() + " ,牛奶";
    }

    @Override
    public double cost() {
        return beverage.cost() + .10;
    }

}

 

客戶端(Client):

StarBuzzCoffee.java:

public class StarBuzzCoffee {
    public static void main(String[] args){
        
        Beverage beverage1 = new DarkRoast();
        beverage1 = new Milk(beverage1);
        beverage1 = new Mocha(beverage1);
        System.out.println(beverage1.getDescription() + "$" + beverage1.cost());
        
        Beverage beverage2 = new HouseBlend();
        beverage2 = new Milk(beverage2);
        beverage2 = new Mocha(beverage2);
        System.out.println(beverage2.getDescription() + "$" + beverage2.cost());
    }
}

 

運行結果:

深焙咖啡 ,牛奶,摩卡$1.3
混合咖啡 ,牛奶,摩卡$1.19

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM