看到字眼,你應該心裡有個數了,所謂裝飾,就是在原有的基礎上加些東西化化裝,有修睫毛的,有化口紅的,有時尚的衣服等等,然後呢就 變漂亮了;比如禮品,都要加個禮品 盒,然後檔次提高了,可以開個好價 ,這也是“裝飾”。 裝飾者模式有個 需要遵循的原則:開閉原則,即對修改關閉,對擴展開放。 什麼情況下需要用到裝飾裝者模式? 我的理解就是:當我已經提供了一些method,而你要使用我的method,那麼你只能在不損壞我的method 的前提下,在我的method的基礎 上 進行擴展,也就是覆蓋處理。 使用裝飾者模式有什麼好處? 就是不損壞需要裝飾的類,也即保護需要裝飾的類。 實例代碼: beverage.java [java] public abstract class Beverage{ String description="Unknown Beverage"; String size="medium"; public String getDescription(){ return description; } public abstract double cost(); public String getSize(){ return size; } public void setSize(String size_){ this.size=size_; } } CondimentDecorator.java [java] public abstract class CondimentDecorator extends Beverage{ public abstract String getDescription(); } Espresso.java [java] public class Espresso extends Beverage{ public Espresso(){ description="Espresso"; } public double cost(){ return 1.99; } } HouseBlend.java [java] public class HouseBlend extends Beverage{ public HouseBlend(){ description="HouseBlend"; } public double cost(){ return 0.89; } } DarkRoast.java [java] public class DarkRoast extends Beverage{ public DarkRoast(){ description="DarkRoast"; } public double cost(){ return 0.99; } } Mocha.java [java] public class Mocha extends CondimentDecorator{ Beverage beverage; public Mocha(Beverage beverage){ this.beverage=beverage; } public String getDescription(){ return beverage.getDescription()+",Mocha"; } public double cost(){ return 0.2+beverage.cost(); } } Soy.java [java] public class Soy extends CondimentDecorator{ Beverage beverage; public Soy(Beverage beverage){ this.beverage=beverage; } public String getDescription(){ return beverage.getDescription()+",Soy"; } public double cost(){ return 0.15+beverage.cost(); } } Whip.java [java] public class Whip extends CondimentDecorator{ Beverage beverage; public Whip(Beverage beverage){ this.beverage=beverage; } public String getDescription(){ return beverage.getDescription()+",Whip"; } public double cost(){ return 0.10+beverage.cost(); } } BeverageSize.java [java] public class BeverageSize extends CondimentDecorator{ public double size=0; public Beverage beverage; public BeverageSize(Beverage beverage){ this.beverage=beverage; } public String getDescription(){ return beverage.getDescription()+","+beverage.getSize(); } public double cost(){ switch(beverage.getSize()){ case "small": return 0.10+beverage.cost(); case "medium": return 0.15+beverage.cost(); case "big": return 0.20+beverage.cost(); default: return 0.15+beverage.cost(); } } } StarBuzzCoffee.java [java] public class StarBuzzCoffee{ public static void main(String args[]){ Beverage beverage = new Espresso(); System.out.println(beverage.getDescription()+'$'+beverage.cost()); Beverage beverage2 = new DarkRoast(); beverage2 = new Mocha(beverage2); beverage2 = new Mocha(beverage2); beverage2 = new Whip(beverage2); beverage2.setSize("big"); beverage2 = new BeverageSize(beverage2); System.out.println(beverage2.getDescription()+'$'+beverage2.cost()); Beverage beverage3 = new HouseBlend(); beverage3 = new Mocha(beverage3); beverage3 = new Mocha(beverage3); beverage3 = new Whip(beverage3); beverage3 = new BeverageSize(beverage3); System.out.println(beverage3.getDescription()+'$'+beverage3.cost()); } } 對應StarBuzzCoffee.java文件,裡面的裝飾類采用了很多new的方法,優化的方法就是使用工廠方法,所謂工廠也就是生產具體實例的地方;工廠方法有區別於抽象工廠。 有關抽象的概念,比如說抽象類和接口,抽象類裡面的方法可以有具體的實現,但是抽象類裡面可以有自己的具體實現的方法;而接口只能在其繼承類的裡面實現方法細節(必須實現)。兩者共同的地方就是 繼承的類有公共的 方法,既然有共同的方法,就提取出來,做成接口(抽象類)。 下面舉例說明下 針對接口編程,不針對實現編程 的原則 : animals.java [java] interface animals { public void bark(); } cat.java [java] class cat implements animals { public void bark() { System.out.println("miao miao"); } } dog.java [java] class dog implements animals { public void bark() { System.out.println("wang wang"); } } test.java [java] public class test{ public static void main(String args[]) { animals a = new dog(); a.bark(); } } dog,cat都有一個bark的方法,把這個方法提取出來作為一個接口聲明。比如說電腦的打印機,電腦提供了USB接口,不論任何打印機只要實現了這個接口,就可以進行打印了,具體怎麼實現的,那是打印機廠家的事情了。 如果現在需要cat的bark方法,那麼只需要把animals a = new dog();改成 animals a = new cat();即可。如果是針對實現編程 ,那麼就是 dog a = new dog(); cat a = new cat();