2012-04-04 84 views
2

這是Decorator模式的一個例子。
是裝飾模式相同的調用超級方法?

public class Computer { 
public String Description(){ 
    return "Computer"; 
} 
} 

public abstract class Decorator extends Computer{ 
public abstract String description(); 
} 

public class Monitor extends Decorator{ 

Computer computer; 
public Monitor(Computer c){ 
    computer = c; 
} 

public String description() { 
    return computer.Description() + " and Monitor"; 
} 
} 

public class main { 
public static void main(String args[]){ 
    Computer c = new Computer(); 
    Monitor m = new Monitor(c); 
    System.out.println(m.description()); 
} 
} 

這與調用超類的super方法相同嗎?就像監視器繼承自計算機,然後調用監視器類中的Description方法內的計算機類中的super.Description()?

回答

5

隨着調用超級方法,您需要爲每種可能性創建一個新的子類。例如,如果你想要一臺帶有顯示器和鼠標的電腦,該怎麼辦?你可以創建一個繼承Monitor的子類。現在說你想要一臺沒有顯示器和鼠標的電腦。您還需要另一個子類,它繼承Computer。只有兩個設備,並且您已經需要三個子類(Monitor,MouseMonitorAndMouse)。如果您的電腦還可以安裝打印機,掃描儀和一組揚聲器,該怎麼辦?

使用裝飾模式,您可以用新設備「裝飾」計算機。就像您對Monitor所做的一樣,您可以爲每個設備製作不同的裝飾器。要建立與所有設備的計算機,你現在就可以做這樣的事情

Computer = new Speakers(
    new Scanner(
     new Printer(
      new Mouse(
       new Monitor(
        new Computer() 
       ) 
      ) 
     ) 
    ) 
); 
computer.description(); 

現在description()回報Computer and Monitor and Mouse and Printer and Scanner and Speakers。您可以將設備與計算機混合搭配,無需爲每個組合創建新的子類。

的留言:

怎麼樣在我的例子中,我刪除裝飾類然後監視didnt從計算機類繼承,而不是我只是把計算機類的實例監視器類裏面,然後做同樣的。

這樣,您只能進入一個級別,只能將一臺設備添加到計算機。實質上,它是一個不可擴展的裝飾器。裝飾者模式是favor composition over inheritance的一種方式,因爲添加多個設備時可能會有巨大的增長。通過你的解決方案,你不需要製作Computer的子類,而是使用Computer構成Monitor,而不願意繼承。它幾乎是一個裝飾者模式,只有你退後一步。

+0

如何在我的例子中,我刪除裝飾類,然後顯示器沒有從計算機類繼承,而是我只是把計算機類的實例內監視類然後做同樣的事情。 – user1293258 2012-04-04 07:53:35

1

簡要回答你的問題:不,它是不一樣的。

裝飾器使用現有的對象來修改它的行爲,但對於外部世界來說,它看起來好像它裝飾類的類型在哪裏。

要解釋這個在你的例子中你有一臺計算機和您的計算機有一些屬性。您的代碼中的某處您正在創建此計算機的一個實例。您正在填寫所有需要的數據。

現在來裝飾器到位。你需要一個類來裝飾你剛創建的計算機的這個實例!恰恰是這一個。

我會接受你的計算機,並添加一個方法將其關閉並

public class Computer { 
    private boolean isOn = true; 
    private String description = "Computer";   

    public vod turnOn(){ 
     this.isOn=true; 
    } 

    public void turnOff(){ 
     this.isOn = false; 
    } 

    public void setDescription(String description){ 
     this.description = description; 
    } 

    public String Description(){ 
     return this.description; 
    } 
} 

現在我創建一個裝飾,在那裏你可以不關閉計算機。

public class ComputerDecorator1 extends Computer { 
    private Computer computer; 

    public ComputerDecorator1(Computer computer){ 
     this.computer = computer; 
    } 

    public vod turnOn(){ 
     this.computer.turnOn(); 
    } 

    public void turnOff(){ 
     System.out.println("You cannot turn me off!!!!"); 
    } 

    public void setDescription(String description){ 
     this.computer.setDescrition(descritption); 
    } 

    public String Description(){ 
     return this.computer.Description(); 
    } 
} 

正如你所看到的,你必須在構造函數中給他一個Computer實例。這是我們裝修的電腦。每個方法的調用都將傳遞給這個類。 通常你必須覆蓋所有傳遞給裝飾對象的方法。在這種情況下,計算機。

您可以使用它來修改對象的行爲,而不用創建它的新類。 好處是,當你從其他地方獲得計算機的實例時,可以添加此過濾器,以便程序的其餘部分無法關閉它。

這是你如何在你的程序中使用裝飾:

public void getMyComputerAndTurnItOff(){ 
    Computer myComputer = getMyComputer(); 
    myComputer.turnOff(); 
} 

public Computer getMyComputer(){ 
    //Here you will load a Computer from an other class 
    Computer computer = this.otherClass.loadComputerFromDB(); 

    //Now we could return it, but what if you shouldn't be able to turn it off? 
    //easy add our decorator 
    return new ComputerDecorator1(computer); 
} 

如果你想使用一個裝飾你需要修改的行爲,否則它是沒用的! 在你的計算機和顯示器從邏輯點的例子中,監視器不能是計算機的裝飾器。對我來說,這是兩個不同的對象。

我希望我能讓它更清楚一點裝飾者是什麼!