Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> 設計模式——裝飾者模式,設計模式裝飾

設計模式——裝飾者模式,設計模式裝飾

編輯:關於android開發

設計模式——裝飾者模式,設計模式裝飾


  裝飾者模式主要體現了OO原則中的“對擴展開放,對修改關閉”這條原則。

  裝飾者模式主要有一下特點:

    1 裝飾者和被裝飾對象有相同的超類型;

    2 你可以用一個或多個裝飾者包裝一個對象;

    3既然裝飾者和被裝飾對象有相同的超類型,所以在任何需要原始對象(被包裝的)的場合,可以使用裝飾過的對象代替它;

    4裝飾者可以在所委托被裝飾者的行為之前與/或之後,加上自己的行為,以達到特定的目的;

    5對象可以在任何時候被裝飾,所以可以在運行時動態地,不限量地用你喜歡的裝飾者來修飾對象。

  裝飾者模式的定義:

  動態地將責任附加到對象上。若要擴展功能,裝飾者提供比繼承更具有彈性的代替方案。

  使用場景舉例:星巴克咖啡的訂單系統,一種咖啡(比如,綜合、深焙、低咖啡因、濃縮)可以加入多種調料(牛奶、摩卡、豆漿、奶泡),比如顧客想要一杯雙倍摩卡豆漿奶泡咖啡,或者牛奶摩卡濃縮咖啡,在這個場景中,基礎的咖啡屬於被裝飾者,而各種調料屬於裝飾者。

  根據裝飾者的特性(裝飾者和被裝飾對象有相同的超類型)所以首先定義一個抽象的Beverage類,這是飲料和調料的基類,飲料和調料都會繼承這個抽象類。

public abstract class Beverage {
    String description = "Unknown Beverage";

    public String getDescription() {
        return description;
    }
    public abstract double cost();

}

 

  基類中有一個飲料描述的屬性,和一個計算價格的抽象方法,同時還有一個獲取描述的getDescription方法

  在聲明一個所有調料的抽象類,也就是裝飾者類,注意這裡是調料!

public abstract class CondimentDecorator extends Beverage {
    public abstract String getDescription();
}

   CondimentDecorator 繼承自Beverage 從而滿足裝飾者和被裝飾對象有相同的超類型。

  現在具體來實現一種飲料吧,以濃縮咖啡為例

public class Espresso extends Beverage {//繼承自Beverage因為Espresso是一種飲料
    public Espresso() {
        // TODO Auto-generated constructor stub
        description = "Espresso";//設置飲料的描述,這裡使用了構造器,或者你也可以使用setter方法。
    }

    @Override
    public double cost() {
        // TODO Auto-generated method stub
        return 1.99;//返回Espresso的價格
    }

}

  現在是各種調料的具體實現

  摩卡的  

public class Mocha extends CondimentDecorator {//繼承自CondimentDecorator保證相同的超類型。
    Beverage beverage;//記錄飲料。

    public Mocha(Beverage beverage) {
        // TODO Auto-generated constructor stub
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        // TODO Auto-generated method stub
        return beverage.getDescription() + ",Mocha";//完整的飲料描述。
    }

    @Override
    public double cost() {
        // TODO Auto-generated method stub
        return .20 + beverage.cost();//返回帶摩卡的咖啡飲料價錢
    }

}

  豆漿的 

public class Soy extends CondimentDecorator {
    Beverage beverage;

    public Soy(Beverage beverage) {
        // TODO Auto-generated constructor stub
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        // TODO Auto-generated method stub
        return beverage.getDescription() + ",soy";
    }

    @Override
    public double cost() {
        // TODO Auto-generated method stub
        return .15 + beverage.cost();
    }

}

  奶泡的

package com.design.patterns.decorator;

public class Whip extends CondimentDecorator {
    Beverage beverage;

    public Whip(Beverage beverage) {
        // TODO Auto-generated constructor stub
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        // TODO Auto-generated method stub
        return beverage.getDescription() + ",whip";
    }

    @Override
    public double cost() {
        // TODO Auto-generated method stub
        return .10 + beverage.cost();
    }

}

  測試一下,比如現在顧客想要一杯甚麼都不加的濃縮咖啡,代碼如下:

public class StarbuzzCoffee {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Beverage beverage=new Espresso();//訂一杯Espresso,不需要調料。
        System.out.println(beverage.getDescription()+" $"+beverage.cost());//打印描述與價格
    }

}

  打印結果

Espresso $1.99

  再來一杯摩卡奶泡的濃縮咖啡

public class StarbuzzCoffee {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Beverage beverage=new Espresso();//濃縮咖啡
        beverage=new Mocha(beverage);//用摩卡裝飾它
        beverage=new Whip(beverage);//用奶泡裝飾它
        System.out.println(beverage.getDescription()+" $"+beverage.cost());//打印描述和價格

    }

}

  打印結果  

Espresso,Mocha,whip $2.29

 

  由以上例子可以看出裝飾者模式巧妙的運用了組合和委托的方式,達到在運行時動態的加上新行為;你可以用無數個裝飾者包裝一個對象;裝飾者的缺點同時也是顯而易見的,那就是使用裝飾者模式會導致設計中出現許多小對象,如果過度使用,會讓程序變得很復雜,所以在實際使用過程中可以使用裝飾者模式+工廠模式的組合形式。

  

  

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved