2012-04-15 4 views
2

Dies ist etwas, das ich ein paar Mal begegnet bin und noch keine befriedigende Antwort gefunden habe. Das scheint ziemlich dumm zu sein, aber nachdem ich das eine Weile gegoogelt habe, konnte ich mir nichts Gutes einfallen lassen.Mehrere optionale Argumente im Konstruktor in Java - exponentielle Anzahl von Konstruktoren

Angenommen, ich habe eine Klasse mit 20 Instanzvariablen, von denen jede optional ist (wird initialisiert oder nicht).

Jetzt möchte ich meine Konstruktoren alle Fälle behandeln, im Falle einiger Instanzvariablen ist es in Ordnung, und ich kann nur Konstruktoren mit unterschiedlichen Signaturen erstellen, aber hier habe ich 20, also würde ich 2^benötigen 20 = 1.048.576 Konstruktoren für alle Fälle! Das scheint ... nicht sehr optimal, stimmst du nicht zu?

Da mit diesem Brute-Force-Ansatz ich im Grunde 2^n Konstruktoren konstruieren muss, wobei n die Anzahl der Instanzvariablen ist, möchte ich einen besseren Weg finden, es zu tun.

Ich habe ein paar Lösungen für dieses Problem gesehen, aber ich glaube, sie alle auf Annahmen über die Daten, aber in meinem Fall kann jede dieser Variablen initialisiert werden oder nicht zufällig, ich habe keine Möglichkeit, das vorher zu wissen Initialisierung.

Ich bin für einige Designmuster oder Ideen suchen, die ich anwenden könnte meinen Code ein bisschen mehr ... wartbar (keine keine Sorge ich 1M + Konstrukteuren nicht schaffen machen :)

Danke.

+1

Bohnenmuster. Konstruktor hat keine Argumente, alle Parameter gehen durch Setter hinein. – bmargulies

+1

das scheint albern, ich sagte, ich habe 20 Instanzvariablen, aber in Wirklichkeit habe ich mehr, ich möchte nicht 20 verschiedene Setter anrufen! Es könnte in inkonsistentem Zustand sein, teilweise durch seine Ausführung, das scheint eine sehr schlechte Lösung zu sein. –

+0

Und dies verbietet mir auch, meine Klasse unveränderlich zu machen. –

Antwort

0
public class YourObject { 
    private Type field1; 
    private Type field2; 
    private Type field3; 
    ... 

    public YourObject() { 
    } 

    public void setField1(Type t) { 
     field1 = t; 
    } 

    public void setField2(Type t) { 
     field2 = t; 
    } 

    public void setField3(Type t) { 
     field3 = t; 
    } 
    ... 
} 
+0

Wie ich oben im Kommentar sagte, ist das Problem mit dieser Art oder Vorgehensweise, dass mein Objekt inkonsistent sein kann, teilweise durch seine Konstruktion! Das ist in meinem Fall sehr gefährlich und das kann ich mir nicht leisten. Und du musst deine Klasse veränderbar machen, was ich nicht möchte. –

+0

@linker Das Objekt befindet sich nur dann in einem inkonsistenten Zustand, wenn es an eine andere Methode übergeben wird, bevor Sie es fertig erstellt haben. Wenn Sie sich über die Änderbarkeit Gedanken machen müssen, könnten Sie ein Flag erstellen, um zu bestimmen, ob die Felder einstellbar sind, und es umschalten, wenn Sie mit der Erstellung Ihres Objekts fertig sind. – Jeffrey

+0

Ich sprach mehr in einem Multi-Thread-Kontext. Sie haben recht, ich konnte sicherstellen, dass das Objekt nicht aufgerufen wird, bevor es fertig ist, aber das erfordert zusätzlichen Aufwand, um die Thread-Sicherheit zu gewährleisten. –

4

die Bean-Muster mit einem Builder Kombinieren. YourObject wird in der Mitte seiner Konstruktion keinen inkonsistenten Zustand haben, aber es werden immer noch mehr als 20 Set-Operationen benötigt und Sie können YourObject unveränderlich machen (wenn Sie wollen) - aber nicht YourObjectBuilder.

public class YourObject { 
    private Type field1; 
    private Type field2; 
    private Type field3; 
    ... 
    YourObject (Type field1 , Type field2 , Type field3 ...) { } 
} 

public class YourObjectBuilder { 
    private Type field1; 
    private Type field2; 
    private Type field3; 
    ... 

    public YourObjectBuilder() { 
    } 

    public YourObject make () { 
     return new YourObject (field1 , field2 , field3 ...) ; 
    } 

    public void setField1(Type t) { 
     field1 = t; 
    } 

    public void setField2(Type t) { 
     field2 = t; 
    } 

    public void setField3(Type t) { 
     field3 = t; 
    } 
    ... 
} 
+0

Das klingt nach einer schönen Lösung und viel besser als das Bean-Muster, danke! –

+0

+1 - Das macht IntelliJ. – duffymo

Verwandte Themen