2017-02-03 4 views
1

Zum Thema „bevorzugen Komposition der Vererbung“, sagt mein Lehrer dies:Zusammensetzung, Spedition und Verpackung

  • Zusammensetzung: die bestehende Klasse wird Bestandteil des neuen
  • Forwarding: jede Methode Instanz in der neuen Klasse, ruft die entsprechende Methode auf die Instanz der enthaltenen bestehenden Klasse und gibt die Ergebnisse
  • wrapper: die neue Klasse kapselt die vorhandene

Ich verstehe sehr gut diese drei Konzepte nicht so ich versuche, einige Code zu notieren:

//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 
    } 
} 

Und so was wickelt?

Antwort

1

Ihr erstes Beispiel ist keine Zusammensetzung.

Composition ist eine „has-a“ Beziehung zwischen Objekten 2, wobei ein Objekt (das zusammengesetzte Objekt) ein Feldelement der anderen (der Besitzer).

Zusammensetzung wäre:

class DemoA { 
    DemoB b; //composition 
} 

Wir würden sagen, "DemoA von Demob zusammengesetzt ist".

Wenn das DemoB Objekt noch verwendbar ist, wenn DemoA nicht mehr erreichbar ist, betrachten wir DemoBaggregated zu sein. Beispielsweise können Schlüssel weiterhin verwendet werden, obwohl der Schlüsselring möglicherweise zerstört wurde. Der Schlüsselring besteht aus Schlüsseln, besitzt diese aber nicht, was eine Aggregation ausdrückt.


Ihr Forwarding Beispiel sieht gut aus, obwohl die Anforderungen sagen „die Ergebnisse zurück“, was die Verfahren könnte darauf hindeuten, nicht leer sein sollte:

class DemoA { 
    private DemoB b; 

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

Was Wrapper , kapseln sie das Verhalten des Objekts ein und zeigen neue (und normalerweise komplexere) Verhaltensweisen auf. Ein Beispiel wäre DataInputStream, das eine umschließt, damit Sie String Objekte und mehr lesen können, wenn nur zu primitiven Daten fähig ist.

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; 
    } 
} 

In diesem Beispiel DemoA Wraps DemoB das readUntil Verhalten aufzudecken, etwas DemoB zu tun unfähig war. Diese

ist etwas ein dummes Beispiel, drückt aber hoffentlich den Punkt: Unser DemoB Objekt nicht Verhalten durchführen können, was wir brauchen (readUntil), so dass wir sie in einer Art wickeln, die das Verhalten für uns behandelt, so dass wir aren‘ t ein solches Verhalten ständig neu zu schreiben.

0

die bestehende Klasse wird Bestandteil des neuen

Versus

die neue Klasse des bestehenden

Es redundantes klingt kapselt.

Wrapper und Zusammensetzung vermitteln in der Tat konzeptionell das Gleiche.

In Ihrem tatsächlichen Beispielcode:

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

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

Die B Klasse bildet eine A Instanz, da es eine A Instanz in seinem Zustand und verwendet sie in der doOtherMethod() Implementierung speichert.
Sie führen jedoch Wrapping/Komposition durch, aber Sie verwenden kein Dispatching-Muster, da die aufgerufenen Methoden nicht symmetrisch zwischen dem Composer und den zusammengesetzten Instanzen sind. Sie rufen tatsächlich b.doOther(), die a.doSomething() ruft.

Eine grundlegende Dispatching Muster wie das aussehen würde:

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

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

Hier rufen Sie genau die gleiche Methode in dem zusammengesetzten Instanz wie in dem Komponisten Beispiel: die doSomething() Methode.
Sie können natürlich einige andere Methoden in der B-Klasse hinzufügen.