2010-11-25 3 views
5

У меня есть открытый класс, которому необходимо передать семь параметров. На данный момент я могу сделать 3 из них переданы конструктору, а еще 4 - общедоступному методу в классе. Например:Обработка более 7 параметров

 

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 
    } 

} 

 

Вопрос в том, является ли это правильным способом попросить клиента класса пройти в параметрах?

+0

Я думаю, что то, что вы должны переходить к конструктору, зависит от ситуации. Можете ли вы подробно объяснить, что делает класс AClass и XClass и каковы эти 7 параметров? – Emil 2010-11-25 05:11:20

+1

«Если у вас есть процедура с десятью параметрами, вы, вероятно, пропустили некоторые». -Alan Perlis :-) – missingfaktor 2010-11-25 05:43:09

ответ

9

Не должно быть ничего, что помешает вам передать 7 параметров конструктору, если это то, что вы хотите. Я не знаю, есть ли максимальное количество параметров, которые могут быть переданы методу на Java, но это, конечно, выше 7, если есть макс.

Когда вы создаете класс и его общедоступные методы, вы создаете интерфейс по использованию и доступу к этому классу. Так технически то, что вы сделали до сих пор, правильно. Правильно ли это, чтобы попросить клиента класса передать аргументы? Это зависит от вас, дизайнера интерфейса.

Моим первым инстинктом, когда я видел 7 передаваемых параметров, было тихо спросить: «Есть ли какая-то связь между некоторыми или всеми этими параметрами, которые могут означать, что они хорошо сочетаются в собственном классе?» Это может быть то, о чем вы обращаетесь, глядя на свой код. Но это вопрос дизайна, а не правильность.

+0

Хороший ответ. Нет «правильного пути», нет четкого превосходного выбора. Вы должны использовать свое лучшее суждение. – 2010-11-25 00:45:12

+0

Как все 7 параметров являются строками, если они все в конструкторе, разве это не смутит людей? Если я создаю фиктивный объект данных, который имеет только установители и получатели для 7 параметров, клиент должен знать об этом типе данных, правильно ли он подходит именно для этой цели? – sarahTheButterFly 2010-11-25 01:05:39

+0

О, абсолютно, это может смутить людей.Но это проблема дизайна, а не техническая. Вот почему я предложил вам посмотреть, что это за параметры, и посмотреть, есть ли способ их инкапсулировать в другой класс. Например, может быть, все семь игроков в какой-то команде. Тогда вы можете обнаружить, что имеет смысл создать класс Team со списком имен игроков внутри него, а затем передать экземпляр Team, а не несколько строк имен игроков. – Marvo 2010-11-25 01:32:58

1

Не можете ли вы просто создать класс/hashmap, который хранит эти параметры и передает это функции?

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

Здесь также обсуждаются идиомы «Именованные параметры» в Java: http://stackoverflow.com/questions/1988016/named-parameter-idiom-in-java – HostileFork 2010-11-25 01:16:42

1

Я действительно не вижу проблемы с этим.

В любом случае вы могли бы создать «запрос» объект или что-то вроде этого:

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"); 
     ... 
    } 
} 

Смотрите также: http://c2.com/cgi/wiki?TooManyParameters

1

Не зная использование класса ребенка, я могу сказать, что есть ничто по своей сути не соответствует тому, что вы сделали.

Примечание, однако, что вы должны объявить

private XClass axClass;

в переменных вашей AClass.

Однако вы говорите: «Я могу сделать ....» Означает ли это, что есть некоторые проблемы с объявлением этого другого?

+0

Спасибо, что Кевин заметил это. Я отредактировал его. Нет никакой проблемы с объявлением всех из них в конструкторе. Я имел в виду, что мне удалось разбить их на 3 и 4. – sarahTheButterFly 2010-11-25 00:46:03

1

Меня это не волнует, потому что объект должен быть на 100% готов к использованию после вызова его конструктора. Это не так написано в вашем примере.

Если параметры, переданные в метод execute, могут быть просто использованы, и это метод, представляющий интерес для клиентов, я не вижу причин, по которым они являются членами данных в классе.

Не зная больше о ваших конечных целях, трудно сказать. Но я бы подумал об этом.

1

Если вы планируете введения AClass.someMethod(), что нужно знать par4-7 без необходимости назвал AClass.excute(), то ясно, что вы должны передать параметры в конструкторе.

С другой стороны: если вы можете построить экземпляр этого объекта с только par1-3 и сделать что-то значимое с ней , кроме вызова excute(), то это имеет смысл, чтобы объект, который будет построен с менее полных семи параметров ,

Однако моя собственная эстетика заключается в том, чтобы попытаться ограничить количество «режимов», в которых может быть объект, в котором работают определенные методы, а другие терпят неудачу. В идеале, полностью построенный объект готов к запуску любого метода, который может вызвать программист. Я бы беспокоился о проблеме дизайна, а не слишком беспокоился о большом числе параметров для конструктора.

Но, как указывали другие, иногда существует естественная группировка этих параметров, которые могут заслуживать собственных. Например: во многих API-интерфейсах вместо передачи (x, y, width, height) по всему пространству они используют объекты прямоугольника.

1

Как уже писали другие, технически корректно передавать 7 параметров, хотя это и не очень удобно для пользователя, если можно так выразиться.

Поскольку вы не много писали об этом классе, я могу предложить одну небольшую вещь: в конструкторе вы просто создаете объект XClass, поэтому было бы разумно создать этот объект раньше и передать его как один параметр.

Что-то вроде этого:

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

И это конструктор:

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

Я бы пойти на Builder Pattern вместо многих параметров конструктора, как предложено

Effective Java Пункт 2: рассмотрите строителя, столкнувшись с большим количеством конструкций т е р параметры

Вот простой класс для иллюстрации:

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; 
     } 

    } 

} 

Вы бы его экземпляр так:

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

Хорошая часть: Вы получаете все преимущества параметров конструктора (например неизменность, если вы этого хотите), но вы также получите читаемый код.

Смежные вопросы