Сколько конструкторов должно быть в классе? - PullRequest
11 голосов
/ 29 января 2009

В настоящее время я модифицирую класс, который имеет 9 различных конструкторов. В целом, я считаю, что этот класс очень плохо спроектирован ... поэтому мне интересно, если это плохой дизайн для класса с таким количеством конструкторов.

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

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

Итак, мой вопрос, как мне исправить эту проблему? Пытаясь уменьшить количество конструкторов? Чтобы все существующие конструкторы принимали параметр ISomeManager?

Конечно, классу не нужно 9 конструкторов! ... и в довершение всего в этом файле 6000 строк кода!

Вот цензурированное представление конструкторов, о которых я говорю выше:

public MyManager()
    : this(new SomeManager()){} //this one I added

public MyManager(ISomeManager someManager) //this one I added
{
    this.someManager = someManager;
}

public MyManager(int id)
    : this(GetSomeClass(id)) {}

public MyManager(SomeClass someClass)
    : this(someClass, DateTime.Now){}

public MyManager(SomeClass someClass, DateTime someDate)
{
    if (someClass != null)
       myHelper = new MyHelper(someOtherClass, someDate, "some param");
}

public MyManager(SomeOtherClass someOtherClass)
    : this(someOtherClass, DateTime.Now){}

public MyManager(SomeOtherClass someOtherClass, DateTime someDate)
{
    myHelper = new MyHelper(someOtherClass, someDate, "some param");
}

public MyManager(YetAnotherClass yetAnotherClass)
    : this(yetAnotherClass, DateTime.Now){}

public MyManager(YetAnotherClass yetAnotherClass, DateTime someDate)
{
    myHelper = new MyHelper(yetAnotherClass, someDate, "some param");
}

Обновление:

Спасибо всем за ваши ответы ... они были превосходны!

Просто подумал, что дам обновленную информацию о том, что я в итоге сделал.

Чтобы решить проблему исключений нулевых ссылок, я изменил дополнительные конструкторы для получения ISomeManager.

В настоящий момент мои руки связаны, когда речь заходит о возможности реорганизовать этот конкретный класс, поэтому я буду помечать его как один в моем списке классов todo, чтобы изменить его, когда у меня будет свободное время. На данный момент я просто рад, что смог реорганизовать класс SomeManager ... он был таким же огромным и ужасным, как этот класс MyManager.

Когда я подойду к редизайну MyManager, я буду искать способ разделить функциональность на два или три разных класса ... или сколько потребуется, чтобы обеспечить выполнение SRP.

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

Ответы [ 16 ]

0 голосов
/ 19 декабря 2012

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

0 голосов
/ 25 марта 2010

Пользователь: NONE

Посмотрите на язык Дилана. У него есть другая система.

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

Конечно, вы можете установить 'required-init-keyword:', и есть другие опции, которые вы можете использовать.

Это работает, и это легко. Я не скучаю по старой системе. Написание конструкторов (и деструкторов).

(кстати, это все еще очень быстрый язык)


0 голосов
/ 29 января 2009

У меня обычно есть один, который может иметь некоторые параметры по умолчанию. Конструктор выполнит только минимальную настройку объекта, поэтому он действителен ко времени его создания. Если мне нужно больше, я создам статические фабричные методы. Вроде как это:

class Example {
public:
  static FromName(String newname) { 
    Example* result = new Example();
    result.name_ = newname;
    return result;
  }
  static NewStarter() { return new Example(); }

private:
  Example();
}

Хорошо, на самом деле это не очень хороший пример, я посмотрю, смогу ли я придумать лучший и отредактировать его.

0 голосов
/ 29 января 2009

Единственный «законный» случай, который я вижу по вашему коду, - это если половина из них использует устаревший тип, который вы работаете над удалением из кода. Когда я так работаю, у меня часто бывают двойные наборы конструкторов, половина из которых помечена как @Deprecated или @Obsolete. Но ваш код, кажется, далеко за пределами этой стадии ...

0 голосов
/ 29 января 2009

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

Это не было прямым ответом на ваш вопрос, но я считаю, что если для класса необходимо иметь более 3-4 конструкторов, это признак того, что он, вероятно, должен быть реорганизован в несколько классов.

С уважением.

0 голосов
/ 29 января 2009

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

Дизайн класса должен заключаться в том, что конструктор создает действительный объект после его завершения. Если вы можете сделать это с 1 параметром или 10 параметрами, пусть будет так!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...