2015-10-19 4 views
1

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

For (рассеянный) Например:

  • enum, где каждое значение является типом представления, например; Alpha, Beta, Charlie.
  • Все три изображения имеют поле Id и Name.
  • Beta также имеет поле Attributes.
  • Charlie также имеет поле ChildId.
  • Все три представления совместно используют ряд методов, например. IsValidFor(...), TriggeredBy(...).
  • Все три представления хранятся в одной и той же таблице базы данных.

Это привело меня иметь один класс с тремя специализированными конструкторами, например:

public enum RepresentationType { Alpha, Beta, Charlie } 

public class Representation 
{ 
    ... 
    public Representation(Guid id, String name) { Type = RepresentationType.Alpha, ... } 
    public Representation(Guid id, String name, String attributes) { Type = RepresentationType.Beta, ... } 
    public Representation(Guid id, String name, Guid childId) { Type = RepresentationType.Charlie, ... } 
} 

Я могу понять, почему я оказался здесь, и в каком-то смысле этот подход имеет смысл; класс представляет собой единый тип вещей, и он имеет много общих функций.

Однако его также проблематично по ряду других причин:

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

Я рассматриваю возможность реорганизации всего этого в набор подклассов, например. RepresentationAlpha, RepresentationBeta, RepresentationCharlie. Это означает, что мне нужно будет написать еще какой-нибудь код, но ничего слишком обременительного. Я вижу проблемы дальше по линии, однако, когда мне нужно работать с представлением из коллекции, и я не знаю, какое представление я на самом деле смотрю.

Это разумный курс действий? Я просто торгую одной проблемой для другой? Есть ли образец дизайна, на который я должен смотреть? Сколько конструкторов слишком много?

редактирует на основе комментариев:

  • Если я суб-класс, я бы, вероятно, также использовать наследование.
  • У меня есть фабричный шаблон для создания каждого отдельного представления, это хранилище каждого интересующего вас представления.
  • Менее важно, если я занимаюсь подклассом, я, вероятно, также сохраню его как важный для данные, с которыми я работаю.
+4

Трудно сказать только из этого, но рассмотрели ли вы наследование, а не использовали перечисления, чтобы отличать ваши объекты? –

+0

С первого взгляда, мне интересно, может ли это быть хорошим вариантом для шаблона Factory? – Tim

+0

Я с Нафаном. Похоже, вам нужен базовый класс и подклассы, а не один класс и свойство типа, которое определяет, какие поля подходят. –

ответ

1

Существует сильное преимущество в том, что у него есть не более одного конструктора.

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

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

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

1

Нет ничего плохого в отношении нескольких конструкторов. Если класс действительно представляет «одну вещь», имеющую один класс, имеет смысл.

Чтобы избежать неинициализированных полей, рассмотрим совместно используемый (возможно, private) конструктор, который будет вызываться из всех ваших других конструкторов для инициализации общих полей.

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

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

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