В чем выигрыш от реализации абстрактным классом интерфейса?

287
05 января 2017, 04:42

В ADO.NET есть классы, наследуются от абстрактных, а абстрактные классы в свою очередь реализуют интерфейс.

Например, есть SqlCommand и OleDbCommand и т п, которые расширяют абстрактный DbCommand, а DbCommand реализует интерфейс IDbCommand.

Короче, все наследуется от абстрактного DbCommand.

Почему Microsoft выбрали такую реализацию? На мой взгляд, можно было обойтись и без интерфейса.

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

Answer 1

Я понимаю принципы дизайна так:

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

Если же у нас есть какой-то обязательный код (к примеру паттерн "шаблонный метод") и мы хотим навязать его использование - выбираем абстрактный класс. Тут программист будет вынужден наследоваться от него.

Если нет требований "навязать", то мы описываем контракт в виде интерфейса и опционально можем родить абстрактные класс(ы) для "boilerplate code"

Применительно к DbCommand - там некая реализация в виде кучи навешанных аттрибутов на свойства и прочее, что является общим для SqlCommand и в OleDbCommand, но интерфейс IDbCommand оставляет свободу тем, кому это не нужно.

На практике вряд ли кто-нибудь будет использовать IDbCommand, но для описания контракта интерфейс предпочтительнее, поэтому у нас есть интерфейс (как описание контракта) и абстрактный класс (как базовый класс позволяющий опционально использовать общий функционал).

ps: эти принципы для публичного кода. В своем же коде интерфейсы(абстрактные классы) стоит рождать только при нужде.

READ ALSO
Как добавить/получить ряд в Linq?

Как добавить/получить ряд в Linq?

Не могу разобраться как добавить новый ряд в таблицу sql

287
CORS и IIS - существуют ли стандартные средства ?

CORS и IIS - существуют ли стандартные средства ?

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

294
DataRow[] + расширение LINQ

DataRow[] + расширение LINQ

Есть массив строк DataRow[] datarowsОдна из колонок имеет имя Sum

374