Количество параметров для конструктора - PullRequest
35 голосов
/ 04 января 2011

У меня есть класс, которому нужно передать 12 параметров его конструктору. Поэтому я думаю, что с дизайном этого класса что-то не так.

Я хотел бы спросить, существует ли какой-либо шаблон проектирования или общий набор правил, касающихся проектирования класса, особенно его конструктора.

Ответы [ 5 ]

37 голосов
/ 04 января 2011

12 параметров определенно звучат слишком много для меня. Варианты уменьшения их числа:

  1. Ввод объекта параметров путем группировки логически связанных параметров в объект и передачи этого объекта вместо отдельных параметров.

  2. Введите Builder (опционально с сцеплением метода ). Это не уменьшает фактический список параметров, но делает код более читабельным и особенно полезно, если у вас есть несколько различных сценариев создания с различными параметрами. Так что вместо

    MyClass someObject = new MyClass(aFoo, aBar, aBlah, aBaz, aBorp, aFlirp, 
            andAGoo);
    MyClass anotherObject = new MyClass(aFoo, null, null, aBaz, null, null, 
            andAGoo);
    

    вы можете иметь

    MyClass someObject = new MyClassBuilder().withFoo(aFoo).withBar(aBar)
            .withBlah(aBlah).withBaz(aBaz).withBorp(aBorp).withFlirp(aFlirp)
            .withGoo(aGoo).build();
    MyClass anotherObject = new MyClassBuilder().withFoo(aFoo).withBaz(aBaz)
            .withGoo(aGoo).build();
    
  3. (Может быть, я должен был начать с этого ;-) Анализировать параметры - действительно ли все они действительно нужны в конструкторе (т.е. обязательно)? Если параметр является необязательным, вы можете установить его через обычный установщик вместо конструктора.

9 голосов
/ 04 января 2011

Если ваша функция принимает одиннадцать параметров, вы, вероятно, забыли еще один

Мне нравится это предложение, потому что оно суммирует все: плохой дизайн требует плохого дизайна.

Я взял это из книги Стандарты кодирования C ++: 101 правила, руководящие указания и лучшие практики , написанной Хербом Саттером, Андреем Александреску.

Редактировать: Прямая кавычка Если у вас есть процедура с десятью параметрами, вы, вероятно, пропустили некоторые . Это само по себе цитата Алана Перлиса .

Функции с таким количеством параметров являются признаком плохого дизайна. Одна из возможностей - попытаться инкапсулировать часть этих параметров в объекте / классе, который имеет определенную цель. (не класс мусора, который бы перечислял все параметры без осмысленной структуры).


Никогда не забывайте Принцип единой ответственности Как следствие, классы остаются ограниченными по размеру, и, как следствие, ограничены по количеству параметров-членов и, следовательно, ограничены по размеру параметров, необходимых для его конструкторов. Как говорится в одном из комментариев ниже, класс с таким большим количеством параметров конструктора может обрабатывать слишком много бесполезных деталей независимо от его главной цели.


Рекомендуется также взглянуть на это: Сколько параметров слишком много?

6 голосов
/ 04 января 2011

12 Параметры, скорее всего, что-то не так с дизайном.

Что делается с параметрами?

  • Класс просто отправляет их в другие конструкторы? Тогда, возможно, ему следует просто принять интерфейсы для готовых построенных объектов.
  • Является ли класс большим и много чего делает со всеми этими параметрами? Тогда класс несет большую ответственность и должен принимать классы, которые позаботятся о деталях.
  • Есть ли какие-либо "кластеры" в параметрах? Возможно, некоторые параметры являются классом при создании. Заключите их в капсулу и возложите на них соответствующую ответственность.

Альтернатива заключается в том, что это параметры для низкоуровневой, критичной к производительности конструкции, и в этом случае конструкция просто должна занять заднее сиденье, но это редко имеет место.

4 голосов
/ 04 января 2011

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

2 голосов
/ 04 января 2011

Я думаю, что это может быть приемлемо, например, при использовании шаблона State. Тем не менее, могу ли я предложить передать объект (если уместно), вместо которого эти параметры? А потом в конструктор загрузка данных с него?

...