2 Stimmen

Best Practices zur Vermeidung von Konstruktor-Kollisionen aufgrund gleicher Parametertypen?

Obwohl es nur selten vorkommt, brauche ich manchmal zwei Konstruktoren mit den gleichen Parametertypen, natürlich mit unterschiedlichen Rollen für jeden Konstruktor. Hier ist ein Beispiel:

public class MyClass {
    public MyClass(String title, String content) {
        // ...
    }

    public MyClass(String title, String link) {
        // ...
    }
}

Ich wäre interessiert zu wissen, was ihr in diesem Fall macht?

  1. Vertauschen Sie die Reihenfolge der Parameter für einen Konstruktor, wenn möglich (nun, nicht in meinem Beispiel)

  2. Geben Sie auf und rufen Sie nach dem Konstruktor einen Setter auf

  3. Es ist noch nie passiert, da es durch Design gelöst werden sollte, wie Polymorphismus/Vererbung

  4. Verwenden Sie ein Designmuster

  5. Fügen Sie einen Dummy-Parameter hinzu, um sie eindeutig zu machen (echt?)

  6. ...


EDIT: Notiz an mich selbst: Ich habe gerade eine schreckliche Sache in java.util.HashSet gefunden: (ziemlich überraschend für eine JDK-Klasse, auch wenn sie paketprivat ist)

/* ......
 * @param dummy  Ignored (distinguishes this constructor from other int, float constructor.)
 * ......
 */
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
    ...
}

4voto

rgettman Punkte 171653

Verwenden Sie das Builder-Muster. Eine verschachtelte Klasse namens Builder akzeptiert Einstellungen, einen Setter-Methodenaufruf nach dem anderen, und eine Methode build() gibt das tatsächliche MyClass-Objekt zurück.

public class MyClass {
   private String title;
   private String content;
   private String link;
   public static class Builder {
      private String title;
      private String content;
      private String link;

      public void setTitle(String title) { this.title = title; }
      public void setContent(String content) { this.content = content; }
      public void setLink(String link) { this.link = link; }
      public MyClass build() {
         return new MyClass(this);
      }
   }

   private MyClass(Builder builder) {
      // Hier validieren.
      if (builder.title == null)
         throw new IllegalArgumentException("Titel ist erforderlich!");
      this.title = builder.title;
      this.content = builder.content;
      this.link = builder.link;
   }
}

Auf diese Weise werden Parameter nicht verwechselt und Konstruktoren vermehren sich nicht aufgrund aller Fälle.

3voto

Chris Gerken Punkte 16058

In diesem Fall können Sie statische Methoden hinzufügen, die eine Instanz der Klasse zurückgeben. Sie können den Namen variieren, wenn Sie gleichartige Argumente haben. Um die Verwendung dieser Methoden zu erzwingen, können Sie einen einzigen, arglosen Konstruktor haben, der als privat deklariert ist.

0voto

Joseph Punkte 569

Vielleicht könnten Sie so etwas machen

public class Link{ /* Konstruktor aus String */ }
public class Inhalt{ /* Konstruktor aus String */ }

Und dann den MyClass-Konstruktor mit den Klassen Link und Inhalt separat überladen

0voto

robermann Punkte 1722

Sie könnten eine Liste von benannten Factory-Methoden verwenden, mit einem privaten Konstruktor: Der Aufrufer kennt nur die Bedeutung der Methoden, deren Implementierung verborgen ist. Später könnten Sie den Code refakturieren, ohne den Aufrufer zu ändern.

I ch finde diese Lösung für Ihren Zweck passender, meiner Meinung nach ist das Erbauer-Muster eine überkonstruierte Lösung (in Ihrem Fall).

public class MyClass {
    private MyClass(String title, String content, String link) {
        // ...
    }

    public static MyClass buildWithLink (String title, String link) {
        return new MyClass(title, null, link);
    }

    public static MyClass buildWithContent (String title, String content) {
        return new MyClass(title, content, null);
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X