Чтобы реализовать свойство или реализовать подкласс - PullRequest
16 голосов
/ 15 мая 2011

У меня есть класс с именем List_Field, который, как следует из названия, создает поля ввода списка.Эти поля ввода списка позволяют пользователям выбирать один элемент для каждого списка.

Я хочу иметь возможность создавать поля ввода списка, которые позволили бы пользователям выбирать несколько элементов в списке, поэтому у меня следующая дилемма:

Должен ли я сделать это путем реализации свойства multiple_choice_allowed в существующем свойстве List_Field, или я должен реализовать подкласс Multiple_Choice_List_Field класса List_Field?

Какой инженерный принцип заключается в том, чтоЯ должен следовать, когда сталкиваюсь с такими дилеммами, как эта?

Ответы [ 5 ]

19 голосов
/ 15 мая 2011

Взгляните на ТВЕРДЫЕ принципы . Они помогут вам в ваших проектах. В частности, принцип единой ответственности скажет вам не смешивать две проблемы в одном классе, а принцип замещения Лискова скажет вам не создавать подклассы, которые нарушают контракт суперклассов, как то, что вы также предлагаете.

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

3 голосов
/ 28 мая 2011

Зависит от наличия / отсутствия эволюции объекта - если вы хотите, чтобы особый случай, подклассификация или инъекция (DI), «выберите» поведение (стратегия) это хорошо.

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

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

Я бы проголосовал за метод свойства / мутирования.

2 голосов
/ 15 мая 2011

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

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

Другое дело для List_Field, вам может потребоваться более одного свойства для обработки нескольких вариантов выбора, в зависимости от текущей реализации.Например, новое свойство для возврата массива выбранных элементов.

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

1 голос
/ 28 мая 2011

Лично я бы сказал, что нет: вместо этого используйте конструктор, который принимает multip_choice_allowed, а затем есть свойство, представляющее ListFields как коллекцию (с одним элементом, когда разрешен только один, и всеми, когда разрешено более одного). Сделайте его доступным только для чтения (это означает, что вы должны копировать его всякий раз, когда возвращаете список).

1 голос
/ 15 мая 2011

Должен ли я сделать это путем реализации свойство multip_choice_allowed в существующее свойство List_Field

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

...