2016-04-05 2 views
1

Bitte beachten Sie den Code:Implementierung von Factory-Methode in verwandten Klassenhierarchien

class X 
{ 
    public string x; 
} 

class Y : X 
{ 
    public string y; 
} 

class A 
{ 
    string a; 
    public virtual X createX<T>() 
    where T : X, new() 
    { 
    return new T() { x = a }; 
    } 
} 

class B : A 
{ 
    string b; 
    public override X createX<T>() 
    { 
    var x = base.createX<T>(); 
    if (x is Y) 
     ((Y)x).y = b; // Yak. 
    return y; 
    } 
} 

... 
var c = new B(); 
var z = c.createX<Y>(); // Yak. I prefer to not needing to know the type Y 

ich diesen Code nicht mag, versuchen, mit dem besseren Weg zu kommen, um es zu Refactoring. Die allgemeine Idee ist ziemlich einfach, jede Klasse der Hierarchie hat eine Factory-Methode, um eine Instanz der Gegenstückklasse der Spiegelhierarchie zu erzeugen. Ich erhalte eine Instanz der Stammklasse oder der abgeleiteten Klasse und muss die Instanz der Gegenstückklasse oder ihre Ableitung (als Root-Gegenstückklasse) zurückgeben. Irgendwelche Ideen oder Entwurfsmuster, die ich stattdessen implementieren kann?

+2

[codereview] (http://codereview.stackexchange.com/)? –

+0

@ S.Akbari Wie verschiebe ich die Frage in den Codereview? –

+0

Melden Sie sich einfach an und posten Sie Ihre Frage. –

Antwort

1

Dies ist, was ich am Ende habe mit. Alle Yacks entfernt. Aber es ist ein bisschen ausführlich.

class X 
{ 
    public string x; 
} 

class Y : X 
{ 
    public string y; 
} 

class A 
{ 
    string a; 
    protected void setX(X x) 
    { 
    x.x = a; 
    } 
    public virtual X createX() 
    { 
    var x = new X(); 
    setX(x); 
    return x; 
    } 
} 

class B : A 
{ 
    string b; 
    protected void setY(Y y) 
    { 
    base.setX(y); 
    y.y = b; 
    } 
    public override X createX() 
    { 
    var y = new Y(); 
    setY(y); 
    return y; 
    } 
} 

... 
var c = new B(); 
var z = c.createX(); 
+0

Schön gemacht, aber denken Sie daran, dass Sie Ihrer Klasse viele Methoden hinzufügen, unabhängig davon, ob Sie eine andere Methode überschreiben. Stellen Sie sich vor, Sie tippen [set ..] und Ihr intelliSense Pop-up mit 42 set-function, dann müssen Sie das richtige auswählen – rocketspacer

+0

Ich stimme zu, es ist ausführlich. Ich kann einfach keine bessere Lösung finden. –

0

Könnte das sein, was Sie wollen?

class BaseProduct 
{ 
    public string x; 
} 

class ChildProduct : BaseProduct 
{ 
    public string y; 
} 

class BaseFactory 
{ 
    string a; 
    public virtual BaseProduct buildProduct(BaseProduct product = null) 
    { 
     if (product == null) 
      product = new BaseProduct(); 

     product.x = a; 
     return product; 
    } 
} 

class ChildFactory : BaseFactory 
{ 
    string b; 
    public override BaseProduct buildProduct(BaseProduct product = null) 
    { 
     if (product == null) 
      product = new ChildProduct(); 
     //else if (!(product is ChildProduct)) 
     // return null or throw exception 

     ((ChildProduct)product).y = b; 
     return base.buildProduct(product); //build BaseProduct.x 
    } 
} 

... 
var cFactory = new ChildFactory(); 
var cProduct = c.buildProduct(); //create a ChildProduct with x=a, y=b 

buildProduct bestimmen, ob es ein neues Produkt seiner eigenen, oder einige abgeleitete Werk aufgefordert wird, zu erstellen angefordert wurde, um seine eigenen Teil zu bauen nur

Sie sollten einige Schutzmechanismus bereitstellen wie überprüfen, ob das Produkt eine abgeleitete Klasse von ChildProduct in ChildFactory.buildProduct ist. Das wird Benutzer vermeiden, vorbei so etwas wie:
childFactory.buildProduct(new BaseProduct()); //yak

+0

Nun, das kümmert sich um den zweiten Yak, obwohl er immer noch den Downcast hasst. Ich habe eine andere Lösung, um beide Yaks zu vermeiden, obwohl sie etwas ausführlich ist. –