裝飾者模式

設計原則:對修改關閉,對擴展開放

 

以星巴克咖啡爲例:

1.拿一個深咖啡對象(DarkRoast)

2.以摩卡(Mocha)對象裝飾它

3.以奶泡(Whip)對象裝飾它

4.調用cost()方法,並依賴委託將咖啡價格加上去

 

裝飾者特點:

1.裝飾者和被裝飾者有相同的超類型

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

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

4.裝飾者可以在被裝飾對象包裝之前或之後,加上自己的行爲,以達到特定的目的 (關鍵點)

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

 

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

 

public abstract class Beverage{

         String description = "Unknown Beverage";

         public abstract dobule coast();

         public String getDescription(){

                return description;

         }

 

}

 

調料抽象類,也就是裝飾者類:

public abstract class CondimentDecorator extends Beverage{

      public abstract String getDescription();//所有調料都必須重新實現該方法

 

}

 

飲料,濃縮咖啡

public class Espresso extends Beverage{

         public Espresso(){

            description = "Espresso";

        }

        public double cost(){

           return 1.99;

        }

}

public class HouseBlend extends Beverage{

         public Espresso(){

            description = "House Blend Coffee";

        }

        public double cost(){

           return 0.89;

        }

}

 

調料代碼:也就是具體的裝飾者

public class Mocha extends CondimentDecorator{

       Beverage beverage;

       public Mocha(Berverage berverage){

           this.berverage = berverage;

       }

       public double cost(){

          return 0.21 + berverage.coast();

       }

       public String getDescription(){

          return berverage.getDescription() + ", Mocha";

       }

 

}

 

測試代碼:

public class StarbuzzCoffee{

    public static void main(String[] str){

        Berverage berverage = new Espresso();

        System.out.println(berverage.getDescription()+"  $"+berverage.cost());//要一杯Espresso,不要添加任何調料

 

        Berverage berverage2 = new HouseBlend();

        berverage2 = new Mocha(berverage2);

        System.out.println(berverage2.getDescirpiton+" $"+berverage2.cost());   //來一杯HouseBlend,用Mocha泡過的

    }

}

 

 

 JDK中的裝飾者模式

 

 

 

 

 

 

 編寫自己的裝飾者:大寫轉成小寫

public class LowerCaseInputStream extends FilterInputStream{

    public LowerCaseeInputStream(InputStream in){

         super(in);

    }

    public int read() throws IOException{

         int c = super.read();

         return (c==-1?c:Character.toLowerCase((char)c));

    }

    public int read(byte[] b,int offset,int len)throws IOException{

        int result = super.read(b,offset,len);

        for(int i = offset;i<offset+result;i++){

          b[i] = Character.toLowerCase((char)b[i]);

        }

        return result;

    }

}

 

測試類:

public class InputTest{

     public static void main(String[] str){

        int c;

        try{

           InputStream c = new LowerCaseInputStream(new BufferedInputStream(new FileInputStream("test.txt")));

           while((c==in.read) >= 0){

               System.out.print((char)c);//只用流來讀取字符,一直到文件尾端。每讀一個字符,就馬上將它顯示出來。

           }

           in.close();

        }catch(IOException e){

             e.printStackTrace();

        }

 

     }

}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章