2016-05-14 4 views
-1

Stellen Sie sich eine Klasse Person vor. Sein Konstruktor benötigt viele Argumente und die Klasse unterliegt nicht Ihrer Kontrolle. Wenn Sie die Erstellung des Objekts vereinfachen möchten, können Sie einen Builder erstellen, mit dem Sie Anweisungen zusammenführen können.Erstellt einen Wrapper, um die Verkettung von Sätzen zu ermöglichen

Wenn Sie jedoch eine Instanz von Person nach der Erstellung ändern möchten, müssen Sie alle ihre Setter einzeln aufrufen.

Wenn Sie häufig große Änderungen vornehmen müssen, ist es akzeptabel, einen Wrapper für Person zu erstellen, der die Verkettung von Setter zulässt? Ich habe die Verkettung meistens nur in Bauarbeitern gesehen, ist es eine schlechte Idee, dass Setter das Objekt, das sie verändert haben, zurückgeben?

Beispielcode mein Denken zu zeigen:

public class Person { 
    String name; 
    int age; 

    public void setName(String name){ this.name = name; } 

    public void setAge(int age){ this.age = age; } 

} 

public class PersonWrapper { 
    Person person = new Person(); 

    public PersonWrapper setName(String name){ 
     this.person.setName(name); 
     return this; 
    } 

    public PersonWrapper setAge(int age){ 
     this.person.setAge(age); 
     return this; 
    } 
} 

public class Example { 
    public void example() { 
      Person p = new Person(); 
      PersonWrapper pw = new PersonWrapper(); 

      //some time later, we want to change these objects 
      p.setName("John"); 
      p.setAge(20);     //this becomes 

      pw.setName("John").setAge(20); //this instead 
    } 
} 

Offensichtlich wäre dies nur dann sinnvoll, wenn es eine etwas große Anzahl von Attributen ist einzustellen. Ich habe nur zwei Attribute zur Verfügung gestellt, um es kurz zu halten.

Hinweis: Es war die Frage Can I do multiple actions to one component in a more elegant way?, die mich das wissen lassen wollte. Am Anfang wollte ich das nur als Kommentar zu der angenommenen Antwort fragen, aber anscheinend ist mein Ruf zu niedrig, um etwas zu sagen. Wenn ich es falsch gemacht habe, dies als neue Frage zu veröffentlichen, lass es mich bitte wissen, damit ich das nächste Mal nicht denselben Fehler mache.

+1

Ich würde 'Builder' oder' Factory' Muster bevorzugen. Das Erstellen einer Wrapper-Klasse für ein komplexes Objekt macht das gesamte Datenmodell komplexer und reduziert die Kontrolle über dieses komplexe Objekt, das in der Wrapper-Klasse verborgen ist. Zum Beispiel, wenn Sie eine Eigenschaft Ihres komplexen Objekts ändern möchten, aber Ihr Wrapper zu diesem Zweck keine geeignete Delegate-Methode besitzt. –

+0

@Rafael Sowohl 'Builder'' als auch' 'Factory'' sind zum Erstellen von Objekten gedacht, und ich habe mich gefragt, ob ich den Objektstatus nach der Erstellung ändern soll. Wie auch immer, wenn ich dich richtig verstehe, um große Änderungen an komplexen Objekten vorzunehmen, benutze einfach seine Setter? Oder möglichst große, veränderbare, komplexe Objekte vermeiden? – SecularisticSloth

+0

Im Allgemeinen sind komplexe Objekte selbst keine gute Idee. Wenn ein Objekt zu komplex ist, sieht es so aus, als ob dieses Objekt zu viel und verantwortlich [für zu viele ** verschiedene ** Aktionen] (https://en.wikipedia.org/wiki/God_object) "weiß". Überdenken Sie das Design Ihrer komplexen Klassen, um diese Klassen in einfachere zu unterteilen, um es ** praktisch ** zu machen, mit ihnen zu arbeiten. Nach dem Entwicklungsprozess sind Bequemlichkeit und Einfachheit Anzeichen dafür, dass Sie auf dem richtigen Weg sind. Und umgekehrt. –

Antwort

1

Wenn Sie wirklich den zusätzlichen Aufwand nur für die Verkettung von Eigenschaften ausgeben möchten (meiner Meinung nach nicht wert), ist Ihre Lösung von Designaspekten in Ordnung. Keine DRY-Violiation, und die Kopplung ist bereits hoch, wenn man Person anstelle von Interfaces benutzt, also tut eine zusätzliche PersonWrapper-Klasse nicht weh. Aber wie bereits erwähnt, bezweifle ich, dass der Nutzen die Mühe wert ist.

Wenn Sie sich nur um den Bauprozess kümmern, empfehle ich Ihnen, über Fabrikmuster nachzudenken.

Eine andere Lösung wäre, eine Dienstprogrammklasse zu verwenden, die die häufigsten Vorgänge für die Personenobjekte bereitstellt. Zum Beispiel:

PersonUtility.SetNameAge(personObject, „John“, „Doe“, 31); 
PersonUtility.SetLook(personObject, weight, height, waistSize, hairColor, eyeColor); 

Aber wenn Sie wirklich mit einem Wrapper-Klasse gehen wollen würde ich den folgenden Ansatz vorschlagen, so dass nur der Wrapper die Verkettung der Fall ist, und alle anderen Operationen mit der ursprünglichen Klasse Person getan werden könnte.

public class Person { 
    private String mName; 
    private int mAge; 

    void setName(String name){ mName = name; } 
    void setAge(int age){ mAge = age; } 

    void printPerson() { 
     System.out.println(mName + " " + mAge); 
    } 
} 

public class PersonWrapper { 
    private final Person mPerson; 

    public PersonWrapper(Person person) { 
     mPerson = person; 
    } 

    PersonWrapper setName(String name) { 
     mPerson.setName(name); 
     return this; 
    } 

    PersonWrapper setAge(int age) { 
     mPerson.setAge(age); 
     return this; 
    } 

    public Person getPerson() { 
     return mPerson; 
    } 
} 

public class Main { 

    public static void main(String[] args) { 
    // write your code here 
     PersonWrapper wrapper = new PersonWrapper(new Person()).setName("John Doe").setAge(31); 

     wrapper.getPerson().printPerson(); 
    } 
} 
+0

Von den Antworten, die mir zur Verfügung gestellt werden, glaube ich, dass dies meine Frage am besten beantwortet. Ich fand es jedoch hilfreich, Rafael Osipovs Kommentare zu der ursprünglichen Frage zu lesen. – SecularisticSloth

+0

Warum nicht einfach Person von seinen Setter zurückgeben? – denniskb

0

Ich bin mir nicht sicher über diese Prozedur, aber vor allem ist es nicht empfohlen, das Objekt der Person innerhalb Ihrer neuen Klasse zu erstellen, dies wird die Abhängigkeit erhöhen, stattdessen können Sie das Objekt außerhalb erstellen und senden Sie es im Konstruktor von "PersonWrapper".

Mein Vorschlag ist es PersonWrapper erben Person wie folgt.

+0

Sicher ist es besser für Sie Factory-Design-Muster, um Ihr Objekt am Anfang zu erstellen –

+0

Wird dies keine Fehler bei der Kompilierung verursachen, weil versucht wird, setName und setAge mit derselben Signatur und einem anderen Rückgabetyp zu überschreiben? – SecularisticSloth

+0

Sorry meine schlechte, ich wollte verschiedene Setter wie setCustomName, setCustomAge verwenden, wird bearbeiten –

Verwandte Themen