Должен ли этот код быть базовым классом вместо интерфейса? - PullRequest
1 голос
/ 12 августа 2009

Интерфейс против Базового класса для меня все еще довольно серая область. Я читаю книгу по ASP.NET 3.5 Enterprise Development, и автор заявляет, что все таблицы будут иметь следующие поля:

InsertDate
InsertENTUserAccountId
UpdateDate
UpdateENTUserAccountId
Version

Если бы я кодировал вышеуказанное требование, я бы создал базовый класс бизнес-объектов, содержащий эти поля, и все бизнес-объекты наследовали бы от него. Тем не менее, автор создал их как интерфейс вместо. Плохая идея? Отличная идея? Не имеет значения?

Обновление

Существует базовый класс, который реализует этот интерфейс. Похоже, что все бизнес-объекты будут наследоваться от базы. Но даже все равно я бы просто поместил этот интерфейс в базовый класс ...?

Ответы [ 9 ]

4 голосов
/ 12 августа 2009

Ну, интерфейс обычно предпочтительнее, так как он обеспечивает большую гибкость и абстракцию - но вы можете сделать и то и другое, имея базовый класс abstract, реализующий интерфейс. Затем 95% времени вы используете базовый класс, а когда вам нужно что-то другое, вы просто используете интерфейс.

Только не трогайте базовый класс из вашего бизнес-кода ... только интерфейс. Базовый класс является только подробностью реализации.

3 голосов
/ 12 августа 2009

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

Используя базовый класс, вы можете использовать одну и ту же реализацию для всех подклассов. Проблемы возникают, если вам нужно создать подкласс другого, так как .NET не допускает множественное наследование. Таким образом, вам придется напрямую реализовать интерфейс (возможно, с использованием композиции).

1 голос
/ 12 августа 2009

Я думаю, что лучший способ взглянуть на интерфейс: msgstr "список сервисов, которые будут предоставлены классом, реализующим этот интерфейс". Примером может быть ISwitchable, все классы, которые реализуют этот интерфейс, предоставляют способ (определенный в интерфейсе) для переключения. Реализация ISwitchable может быть кнопкой.

С другой стороны, отношение база / подкласс может быть описано как: Подкласс - это специализация базового класса. Таким образом, если у вас есть домашнее животное в качестве базового класса, вы можете иметь собаку, выведенную из базы, так как это специализация домашнего животного. Вы не можете сказать, что собака предоставляет услуги домашних животных. В этом примере класс dog может реализовывать интерфейс IBrag.

Я не согласен с каким-то ответом, который говорит «когда» что-то должно быть интерфейсом или базовым классом. Это часть процесса моделирования, поэтому он зависит от бизнес-объектов и контекста, должен ли быть интерфейс или базовый класс.

1 голос
/ 12 августа 2009

Вид того, что говорили другие парни, но мой простой способ думать об этом:

  • Если вы хотите, чтобы он выглядел так же снаружи, сделайте его интерфейсом.
  • Если вы хотите, чтобы он был таким же внутри, сделайте его базовым классом.
  • Возможно, вы захотите сделать и то, и другое.
1 голос
/ 12 августа 2009

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

1 голос
/ 12 августа 2009

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

РЕДАКТИРОВАТЬ: если вы думаете об этом, не все таблицы имеют одинаковые данные, но все они должны что-то делать с учетной записью. Это отношение поведения в отличие от отношения is-a, то есть интерфейса.

0 голосов
/ 12 августа 2009

Я думаю, вы должны думать о интерфейсах, подобных поведению, которые должен реализовывать тип, не думая о том, что это за тип.Они должны быть легкими и позволять приходить к вашим объектам и сторонним объектам.Базовый класс имеет большее отношение к семейству классов, которые его унаследуют, и поэтому должен иметь некоторую семантическую связь с.И, конечно, вы можете использовать и то, и другое.У вас должен быть интерфейс ILoggable (я полагаю, вы используете эту информацию для ведения журнала) или что-то еще, и на основе вашей системной архитектуры вы можете иметь один или несколько базовых классов, которые реализуют этот интерфейс, например, чтобы избавить вас от кодирования повторяющегося кодаAbstractPerson, который будет реализовывать ILoggable и объект Person наследует его, этот подход расширяется в будущем, его легко внедрить в чужой код и дает вам гибкость.

0 голосов
/ 12 августа 2009

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

IBaseInterface {
 //basic fields
}

ITable1Interface : IBaseInterface

BaseClass : IBaseInterface {
  //basic fields implementation
}

Table1Class : BaseClass...
0 голосов
/ 12 августа 2009

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

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