Frage

Im Folgenden sind die zwei Ansätze:

  • Konstruktor mit allen Klasseneigenschaften

Pros: Ich habe eine genaue Anzahl von Typen von Parametern eingeben, damit, wenn ich einen Fehler mache die Compiler mich (übrigens warnen, ist es eine Möglichkeit, das Problem, auf der Parameterliste irrtümlich eingeschaltet zwei Integer zu verhindern? )

Nachteile: Wenn ich habe viele Eigenschaften kann die Instantiierung Linie wirklich lang werden und es könnte über zwei oder mehr Zeilen

umspannt
  • Setter und der Standard leere Konstruktor

Pros: Ich kann klar sehen, was ich einstellen, so dass, wenn ich etwas falsch zu machen bin ich es genau bestimmen kann, sobald ich es bin eingeben (Ich kann nicht die previuos Fehler machen Schalt zwei Variablen von der gleicher Typ)

Nachteile:. Die Instanziierung eines Objekts mit vielen Eigenschaften könnten mehrere Linien nehmen (weiß nicht, ob dies wirklich ein con ist) und wenn ich der Compiler eine Eigenschaft festlegen nicht vergessen, etwas sagen

Was werden Sie tun, und warum? Haben Sie irgendLichtMuster kennen (man denke, dass es jedes Mal ein Objekt wth 7+ Eigenschaften verwendet werden soll instanziiert) vorschlagen? Ich frage das, weil ich dazu neigen, große Konstrukteuren zu mögen, wo ich nicht schnell herausfinden kann, wo die Variable ist, die ich suche, auf der anderen Seite finde ich die „setzt alle Eigenschaften“ anfällig für einige der Eigenschaften fehlen.

Fühlen Sie sich frei zu Argumente meiner Annahmen in Vor-und Nachteile, wie sie sind nur meine Gedanken:)

Update - eine Frage, die ich gefunden habe, die im Zusammenhang mit dieser ist: Gebäude groß, unveränderliche Objekte ohne Konstrukteuren mit langen Parameterlisten

War es hilfreich?

Lösung

Sie können an dem Builder-Muster von Joshua Bloch, und beschrieben in Effective Java befürwortete aussehen. Es gibt eine Präsentation mit den wichtigsten Punkten auf http: //developers.sun .com / Lernen / javaoneonline / 2007 / pdf / TS-2689.pdf ; kein Zweifel, könnten Sie einen besseren Bezug raben.

Grundsätzlich haben Sie eine andere Klasse, wahrscheinlich eine innere Klasse, die nach den Eigenschaften festgelegt wird, und die den ursprünglichen Erbauer zurückkehren genannten Methoden bietet, so dass Sie können Kette Anrufe. Es macht für eine recht lesbares Stück Code.

Zum Beispiel, nehmen wir an, ich habe eine einfache Message mit einigen Eigenschaften. Der Client-Code dieser Konstruktion könnte einen Builder verwenden, um einen Message herzustellen, wie folgt:

Message message = new Message.Builder()
    .sender( new User( ... ) )
    .recipient( new User( ... ) )
    .subject( "Hello, world!" )
    .text( messageText )
    .build();

Ein Fragment von Message.Builder könnte ähnlich aussehen wie folgt:

public class Builder {

    private User sender = null;
    // Other properties

    public Builder sender( User sender ) {
        this.sender = sender;
        return this;
    }
    // Methods for other properties

    public Message build() {
        Message message = new Message();
        message.setSender( sender );
        // Set the other properties
        return message;
    }

}

Andere Tipps

Sie haben die größte Pro von mit einem Konstruktor mit vielen Parametern verpasst. Es können Sie unveränderliche Typen erstellen

Der normale Weg zur Schaffung von unveränderlichen Typen ohne riesigen Konstruktor Bösartigkeit ist ein Helfer-Typ haben - ein builder , die die Werte unterhält Sie in Ihrem letzten Objekt wollen werde, dann baut das unveränderliche Objekt, wenn Sie bereit sind.

Neue wissenschaftliche Forschung (CMU und Microsoft) auf API Benutzerfreundlichkeit legt nahe, dass mit Setter Standardkonstruktoren die Art und Weise in Bezug auf Benutzerfreundlichkeit zu gehen wäre. Dies ist von „Usability Auswirkungen der Erfordern Parameter in Objekten Konstrukteurs“ von Jeff Stylos und Steven Clarke und wurde bei der Internationalen Konferenz über Software Engineering vorgestellt:

Zusammenfassung : Die Verwendbarkeit von APIs wird immer wichtiger, die Produktivität Programmierern. Aufgrund der Erfahrungen mit Usability-Studien von spezifischen APIs wurden Techniken erforscht für die Nutzbarkeit von Design-Entscheidungen, die in viele APIs zu studieren. Eine vergleichende Studie wurde zur Beurteilung durchgeführt, wie professionelle Programmierer in der Konstrukteurs Objekte APIs mit den erforderlichen Parametern verwenden im Gegensatz ‚default‘ Konstrukteurs parameterlos. Es wurde vermutet, dass erforderlichen Parameter mehr verwendbar und selbst dokumentieren APIs Programmierer durch die Führung in Richtung auf die korrekte Verwendung von Objekten und verhindert Fehler schaffen würde. Doch in der Studie wurde festgestellt, dass entgegen den Erwartungen, Programmierer stark bevorzugt und waren effektiver mit APIs, die nicht Konstruktorparameter erforderte. Teilnehmerverhalten analysiert die kognitiven Dimensionen Framework, und enthüllt, dass erforderlich Konstruktorparameter stört gemeinsame Lernstrategien, wodurch unerwünschtes vorzeitiges Engagement.

Sie erwähnen es in Ihrem Beitrag, aber ich denke, das ist ein wichtiger Punkt ist, die mehr Aufmerksamkeit verdient: es sei denn, jeder Eingabeparameter eine andere Art, das große Problem mit großen Konstrukteuren ist, dass es sehr leicht ein paar Variablen transponieren. Der Compiler ist ein unzuverlässiges Sicherheitsnetz - es einige Fehler zu fangen, aber diejenigen, die durchrutschen sind viel schwieriger sein werden zu identifizieren und zu debuggen. Vor allem, weil die Eingangsliste für einen großen Konstruktor ist ziemlich undurchsichtig, wenn Sie die API offen in einem anderen Fenster haben.

Getter und Setter sind wesentlich einfacher zu debuggen, vor allem, wenn Sie Sicherheitseinrichtungen einleiten, die eine Laufzeitausnahme, wenn das Objekt werfen ist nicht richtig ausgefüllt. Und ich bin ein großer Fan von „leicht zu debuggen.“

Vor diesem Thread habe ich nie von dem Builder-Muster gehört hatte Rob erwähnt. Nie benutzt es selbst (natürlich), aber es ist verdammt faszinierend.

Ich ziehe es unter Konstruktorargumente, für die oben genannten Unveränderlichkeit Gründen. Wenn das gibt Ihnen einen Konstruktor, der viele Argumente (sagen mehr als vier oder so) hat, das ist ein Code Geruch zu mir:. Einige dieser Argumente sollten zusammen in ihre eigenen Arten gebündelt werden

Zum Beispiel, wenn Sie so etwas wie diese:

class Contact
{
    public Contact(string firstName, string lastName, string phoneNumber,
        string street, string city, string state, int zipCode) { ... }
}

Ich werde Refactoring es an:

class Contact
{
    public Contact(Person person, PhoneNumber number, Address address) { ... }
}

class Person
{
    public Person(string firstName, string lastName) { ... }
}

class PhoneNumber
{
    public PhoneNumber(string digits) { ... }
}

class Address
{
    public Address(string street, string city, string state, int zipCode) { ... }
}

zu großen Klassen sind ein wirklich gemeinsames Designproblem in OOP Codebases.

Es gibt noch andere Aspekte. Wenn Sie möchten, zur Entwurfszeit bestimmte Dinge mit Ihrer Klasse in der Lage sein, anstatt nur zur Laufzeit, zum Beispiel Ihre Klasse als ein Objekt in der Objektpalette hinzugefügt (dies wird mit Hilfe von Java Netbeans) Sie zur Verfügung stellen müssen einen Konstruktor ohne Argumente in um in der Lage zu sein, dies zu tun.

Es gibt noch andere Strategien auch hier. Bevor Sie versuchen, herauszufinden, wie mit vielen Parametern zu behandeln, ich denke, es ist wichtig, Ihr Design neu zu besuchen und schauen, ob Ihre Klasse zu viel tut. Sehen Sie, wenn Sie gruppieren können einige der Parameter zusammen in eine neue Klasse, und ein bestimmtes Verhalten in dieser Klasse bewegen.

  

Setter und der Standard leere Konstruktor

JRL berührt schräg drauf , aber ein Grund, Setter zu prüfen, ist das Objekt zu haben, auf die JavaBean Spezifikation . Dies macht Instanzen zugänglich Bearbeitung über Selbstbeobachtung Tools und Ausdauer mit bestimmten Serialisierungstechniken .

Wer sagt, dass man nicht beides tun kann? Ich würde sagen, obligatorische Eigenschaften gehen in den Konstruktor, sind optional solche mit Setter behandelt. BTW, der sagt, Sie brauchen immer eine Setter pro Objekt? Wenn zwei Eigenschaften zusammen konzeptionell gehören, warum nicht setzen sie zusammen?

Ich mag das Builder-Muster auch, aber die wichtigste Regel ist: immer Ihr Gehirn benutzen und das Design zu finden, die am besten das spezifische Problem paßt. Es gibt keine one-size-fits-all-Lösung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top