2017-02-03 52 views
1

對主題「寧​​可組成了繼承」,我的老師這樣說:組成,轉發和包裝

  • 組成:現有的類將成爲新的一個
  • 轉發的一個組成部分:每個實例方法在新的類,調用了現有的類的實例包含相應的方法並返回結果
  • 包裝:新類封裝現有

我不太明白這三個概念,所以我試着寫下一些代碼:

//Composition is this 
Class A{ 
    public void doSomething(){ 
     //do some code 
    } 
} 

Class B{ 
    A a = new A(); 
    public void doOther(){ 
     a.doSomething(); //this is forwarding 
    } 
} 

那麼什麼是包裝呢?

回答

1

你的第一個例子不是組合。

Composition是2名對象,其中一個對象(所構成的對象)是其他的場構件(所有者)之間的「has-a」的關係。

組成是:

class DemoA { 
    DemoB b; //composition 
} 

我們會說: 「DemoA由復員的」。

如果DemoB對象仍然是可用的,當DemoA變得無法訪問,我們認爲DemoBaggregated。例如,雖然密鑰環可能已被破壞,但仍可使用密鑰。密鑰環由密鑰組成,但不擁有它們,表示聚合。


你轉發的例子看起來不錯,但要求不要說「返回結果」,這可能意味着該方法不應該是無效的:

class DemoA { 
    private DemoB b; 

    public int doSomething() { 
     return b.doSomething(); //forwarding/delegating 
    } 
} 

至於包裝,它們封裝了對象的行爲,暴露了新的(通常更復雜的)行爲。一個例子是DataInputStream,它包裝InputStream以允許您讀取String對象和更多,當InputStream只有原始數據時。

class DemoB { 
    public int read() { 
     //...Read one int of data 
    } 
} 

class DemoA { 
    private DemoB b; 

    public DemoA(DemoB b) { 
     this.b = b; 
    } 

    public List<Integer> readUntil(List<Integer> dataList, Supplier<Boolean> condition) { 
     while(condition.get()) 
      dataList.add(b.read()); 

     return dataList; 
    } 
} 

在這個例子中,DemoA包裹DemoB揭露readUntil行爲,一些DemoB無法執行的。

這有點傻例子,但希望表達一點:我們DemoB對象不能執行的行爲,我們需要(readUntil),所以我們把它包在處理的行爲對我們是一個類型的,所以我們不是活得不斷重寫這種行爲。

0

現有類成爲新的一個

的對戰

一個組件的新類封裝現有

聽起來冗餘。

包裝和構圖在概念上傳達了同樣的東西。

在您的實際示例代碼:

class A{ 
    public void doSomething(){ 
     //do some code 
    } 
} 

class B{ 
    A a = new A(); 
    public void doOther(){ 
     a.doSomething(); //this is forwarding 
    } 
} 

,因爲它在它的狀態存儲A實例,並使用它在doOtherMethod()實現的B類組成一個A實例。
儘管如此,您可以執行包裝/合成,但不使用調度模式,因爲所調用的方法在作曲者和合成實例之間不是對稱的。您的確稱爲b.doOther(),即a.doSomething()

一個基本的調度模式將看起來像:

class A{ 
    public void doSomething(){ 
     //do some code 
    } 
} 

class B{ 
    A a = new A(); 
    public void doSomething(){ 
     a.doSomething(); //this is forwarding 
    } 
} 

在這裏,您撥打正是在構成的情況下同樣的方法,在作曲家實例:doSomething()方法。
您可以在B課程中添加一些其他方法。