2010-11-25 8 views
5

Ich habe eine öffentliche Klasse, die 7 Parameter benötigt, die übergeben werden sollen. Im Moment bin ich in der Lage, 3 von ihnen an den Konstruktor und weitere 4 an eine öffentliche Methode in der Klasse zu übergeben. Wie folgt aus:Handhabung von mehr als 7 Parametern

 

Public Class AClass{ 
    private XClass axClass; 
    private String par4; 
    private String par5; 
    private String par6; 
    private String par7; 

    public AClass(String par1, String par2, String par3){ 
     aXClass = new XClass(par1,par2,par3); 
    } 

    public execute(String par4,String par5, String par6, String par7){ 
     //this is needed because they are used in other private methods in this class 
     this.par4 = par4; 
     this.par5 = par5; 
     this.par6 = par6; 
     this.par7 = par7; 

     //call other private methods within this class. 
     //about 7 lines here 
    } 

} 

 

Meine Frage ist, dann ist dies der richtige Weg Client der Klasse zu fragen, in paramters zu vorbei?

+0

Ich denke, was Sie an Konstruktor übergeben sollten hängt von der Situation ab. Können Sie im Detail erklären, was AClass und XClass und was diese 7 Parameter sind? – Emil

+1

"Wenn Sie eine Prozedur mit zehn Parametern haben, haben Sie wahrscheinlich einige verpasst." -Alan Perlis :-) – missingfaktor

Antwort

9

Es sollte nichts sein, was Sie davon abhält, 7 Parameter an einen Konstruktor zu übergeben, wenn Sie das wollen. Ich weiß nicht, ob es eine maximale Anzahl von Parametern gibt, die an eine Methode in Java übergeben werden können, aber es ist sicherlich höher als 7, wenn es eine max.

Wenn Sie eine Klasse und ihre öffentlichen Methoden erstellen, erstellen Sie eine Schnittstelle für die Verwendung und den Zugriff auf diese Klasse. Technisch also, was du bisher gemacht hast, ist richtig. Ist es der "richtige Weg", den Klienten einer Klasse zu bitten, Argumente zu übergeben? Das liegt an dir, dem Designer der Schnittstelle.

Mein erster Instinkt, als ich sah, dass 7 Parameter bestanden wurden, war, still zu fragen: "Gibt es eine Beziehung zwischen einigen oder allen dieser Parameter, die bedeuten könnten, dass sie in einer eigenen Klasse gut zusammenpassen?" Das ist möglicherweise etwas, das Sie ansprechen, wenn Sie sich Ihren Code ansehen. Aber das ist eine Frage des Designs, nicht die der Korrektheit.

+0

Gute Antwort. Es gibt keinen "richtigen Weg", keine klar überlegene Wahl. Sie müssen Ihr bestes Urteilsvermögen verwenden. –

+0

Da alle 7 Parameter Strings sind, wenn sie alle im Konstruktor sind, wird das nicht verwirren? Wenn ich ein Dummy-Datenobjekt erstelle, das nur Setter und Getter für die 7 Parameter hat, muss der Client über diesen Datentyp Bescheid wissen, ist es der richtige Ansatz nur für diesen Zweck? – sarahTheButterFly

+0

Oh, absolut, es könnte Leute verwirren.Aber das ist ein Design-Problem im Gegensatz zu einem technischen. Deshalb habe ich vorgeschlagen, dass Sie sich ansehen, was diese Parameter sind, und sehen, ob es eine Möglichkeit gibt, sie in eine andere Klasse zu kapseln. Zum Beispiel sind vielleicht alle sieben Spieler in einem Team. Dann ist es möglicherweise sinnvoller, eine Team-Klasse mit einer Liste von Spielernamen zu erstellen und dann eine Instanz von Team statt mehrerer Strings mit Spielernamen zu übergeben. – Marvo

1

Kannst du nicht einfach eine Klasse/hashmap erstellen, die diese Parameter speichert und diese an die Funktion weitergibt?

public excute(Storageclass storageClass){ 
     //this is needed because they are used in other private methods in this class 
     this.par4 = storageClass.getPar4(); 
     this.par5 = storageClass.getPar5(); 
     this.par6 = storageClass.getPar6(); 
     this.par7 = storageClass.getPar7(); 

     //or 
     this.storageClass = storageClass; 
    } 
+0

Es gibt auch einige Diskussionen über "benannte Parameter" Idiome in Java: http://StackOverflow.com/Questions/1988016/Named-Parameter-Idiom-in-Java – HostileFork

1

Ich sehe das Problem nicht wirklich damit.

In jedem Fall, dass Sie ein „Anforderung“ Objekt oder so etwas wie dies schaffen könnten:

class SomeClass { 
    private String a; 
    private String b; 
    .... 
    public SomeClass(Request r) { 
     this.a = r.get("a"); 
     this.b = r.get("b"); 
     ... 
    } 

    public void execute(Request other) { 
     this.d = other.get("d"); 
     this.e = other.get("d"); 
     ... 
    } 
} 

Siehe auch: http://c2.com/cgi/wiki?TooManyParameters

1

Ohne zu wissen, die Verwendung der Kind-Klasse, kann ich sagen, dass es nichts an sich falsch mit dem, was Sie getan haben.

Beachten Sie aber, dass Sie

private XClass axClass;

in den Variablen Ihres AClass zu erklären haben.

Allerdings sagen Sie "Ich kann ...". Bedeutet das, dass es ein Problem gibt, dies anders auszudrücken?

+0

Danke Kevin dafür, das zu bemerken. Ich habe es bearbeitet. Es gibt kein Problem damit, alle im Konstruktor zu deklarieren. Was ich meinte war, ich schaffte es, sie in 3 und 4 zu teilen. – sarahTheButterFly

1

Ich interessiere mich nicht viel, weil ein Objekt 100% bereit sein sollte, nachdem sein Konstruktor aufgerufen wird. Es ist nicht wie in Ihrem Beispiel geschrieben.

Wenn die an die execute-Methode übergebenen Parameter einfach konsumiert werden können, und das ist die Methode, die für Clients von Interesse ist, sehe ich keinen Grund dafür, dass sie Datenmitglieder in der Klasse sind.

Ohne mehr über Ihre ultimativen Ziele zu wissen, ist es schwer zu sagen. Aber ich würde diese Umsetzung überdenken.

+0

Hallo Duffymo! Entschuldigung, ich will nur Hallo sagen. Wahrscheinlich nicht geeignet, aber :) – sarahTheButterFly

+0

Perfekt in Ordnung, Sarah. Wenn Sie in Amerika sind, hoffe ich, dass Sie morgen einen schönen Urlaub haben. – duffymo

+0

hehe. Ich bin nicht in Amerika. Aber trotzdem danke. Und es ist auch morgen hier - Australien. genießen Sie Ihren Urlaub :) – sarahTheButterFly

1

Wenn Sie einen AClass.someMethod() vorstellen, der par4-7 kennen muss, ohne dass Sie AClass.excute() aufgerufen haben müssen, dann sollten Sie die Parameter im Konstruktor eindeutig übergeben.

Auf der anderen Seite: Wenn Sie mit nur eine Instanz dieses Objekts konstruieren können par1-3 und neben Anruf excute() dann damit etwas Sinnvolle tun macht es Sinn, das Objekt zu ermöglichen, mit weniger als die vollen sieben Parameter gebaut werden .

Meine eigene Ästhetik besteht darin, zu versuchen, die Anzahl der "Modi" zu begrenzen, in denen ein Objekt funktionieren kann und andere scheitern. Im Idealfall ist ein vollständig konstruiertes Objekt bereit, jede Methode auszuführen, die der Programmierer aufrufen könnte. Ich mache mir mehr Gedanken über das Design-Problem als über die bloße Anzahl von Parametern für den Konstrukteur.

Aber wie andere gezeigt haben, gibt es manchmal eine natürliche Gruppierung dieser Parameter, die eigene Objekte verdienen können. Zum Beispiel: in vielen APIs anstelle von (x, y, width, height) überall an der Stelle verwenden sie Rechteckobjekte.

+0

Auch: ist deine Schreibweise http://de.wiktionary.org/wiki/execute absichtlich oder unabsichtlich? Normalerweise würde ich einfach annehmen, dass ein Tippfehler nicht erwähnenswert ist, aber ich habe vor einer Minute eine Methode namens subGridRowColapsed gesehen, die es in die jqGrid-API geschafft hat ... muss überprüft werden. http://www.trirand.com/jqgridwiki/doku.php?id=wiki:subgrid&s[]expand – HostileFork

+0

Entschuldigung, es ist unbeabsichtigt. Tippfehler. : P – sarahTheButterFly

1

Wie andere bereits geschrieben haben, ist es technisch korrekt, 7 Parameter zu übergeben, obwohl nicht sehr "benutzerfreundlich", wenn Sie das sagen können.

Da Sie nicht viel über diese Klasse geschrieben haben, kann ich eine kleine Sache vorschlagen: Im Konstruktor erstellen Sie nur XClass Objekt, also wäre es vernünftig, dieses Objekt vorher zu erstellen und es als einen einzelnen Parameter zu übergeben.

Etwas wie folgt aus:

... 
XClass aXClass = new XClass(par1, par2, par3); 
AClass aClass = new AClass(aXClass); 
... 

Und dies ist der Konstruktor:

public AClass(XClass aXClass) { 
     this.aXClass = aXClass; 
} 
6

ich für die Builder Pattern statt vieler Konstruktorparameter wie vorgeschlagen gehen würde durch

Effective Java Punkt 2: Betrachten Sie einen Builder, wenn Sie mit vielen Constru konfrontiert sind Ctor Parameter

Hier ist eine einfache Klasse ist, zu veranschaulichen:

public class Dummy { 

    private final String foo; 
    private final String bar; 
    private final boolean baz; 
    private final int  phleem; 

    protected Dummy(final Builder builder) { 
     this.foo = builder.foo; 
     this.bar = builder.bar; 
     this.baz = builder.baz; 
     this.phleem = builder.phleem; 
    } 

    public String getBar() { 
     return this.bar; 
    } 

    public String getFoo() { 
     return this.foo; 
    } 

    public int getPhleem() { 
     return this.phleem; 
    } 

    public boolean isBaz() { 
     return this.baz; 
    } 

    public static class Builder { 
     private String foo; 
     private String bar; 
     private boolean baz; 
     private int  phleem; 

     public Dummy build() { 
      return new Dummy(this); 
     } 

     public Builder withBar(final String bar) { 
      this.bar = bar; 
      return this; 
     } 

     public Builder withBaz(final boolean baz) { 
      this.baz = baz; 
      return this; 
     } 

     public Builder withFoo(final String foo) { 
      this.foo = foo; 
      return this; 
     } 

     public Builder withPhleem(final int phleem) { 
      this.phleem = phleem; 
      return this; 
     } 

    } 

} 

Sie würden instanziiert es wie folgt aus:

Dummy dummy = new Dummy.Builder() 
        .withFoo("abc") 
        .withBar("def") 
        .withBaz(true) 
        .withPhleem(123) 
        .build(); 

Das schöne Teil: Sie erhalten alle Vorteile der Konstruktorparameter (z.B Unveränderlichkeit, wenn Sie es wollen), aber Sie erhalten auch lesbaren Code.

+0

+1, ich zweite diese Antwort. – missingfaktor

+1

Sie müssen eine Überprüfung der build() - Methode hinzufügen, um zu überprüfen, ob alle "obligatorischen" Parameter gesetzt wurden, um genau einem Konstruktor mit 7 Parametern zu entsprechen (dh: zwischen einer Benutzereinstellung "null" und der Standardwert "Null" Das ist der Nachteil dieser Lösung imho. – naab

+1

@naab in diesen Tagen würde ich das https://immutables.github.io/ Framework zum Generieren der Builder verwenden. Diese Funktion wird standardmäßig standardmäßig hinzugefügt –

Verwandte Themen