Абстрактный класс или интерфейс для сервиса IoC? - PullRequest
7 голосов
/ 25 марта 2011

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

Я нашел это полезным в сочетании с шаблоном шаблона для уменьшения повторения. Например, укажите класс Product со свойством IsActive Я мог бы использовать интерфейс для хранилища, например:

interface IProductRepository
{
    IEnumerable<Product> Load();
}

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

IEnumerable<Product> activeProducts = repository.Load().Where(x => x.IsActive);

Где repository - конкретная реализация. Если бы я использовал абстрактный класс, такой как:

abstract class ProductRepository
{
    protected abstract IEnumerable<Product> LoadCore();

    public IEnumerable<Product> Load()
    {
        return LoadCore().Where(x => x.IsActive);
    }
}

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

IEnumerable<Product> activeProducts = repository.Load();

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

Есть ли польза от использования интерфейса вместо абстрактного класса? С какими потенциальными недостатками использования абстрактных классов я могу столкнуться?

Я использую Castle Windsor в качестве контроллера IoC и .Net framework 3.5.

Ответы [ 2 ]

7 голосов
/ 25 марта 2011

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

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

Абстрактные базовые классы обычно являются лучшим выбором из-за этого.Я не думаю, что есть какой-то недостаток в использовании абстрактного базового класса, кроме вопросов о поддержке, таких как «почему я не могу создать экземпляр этого типа?»

2 голосов
/ 28 марта 2011

Рекомендация взята из Руководства по проектированию структуры . Эта рекомендация Microsoft существует специально для многократно используемых библиотек классов. Другими словами: фреймворки, подобные самой платформе .NET. Если вы создаете бизнес-приложение, это руководство не применяется. Это не применимо, потому что маловероятно, что у вас будут проблемы с версиями в бизнес-приложениях, потому что вы контролируете весь клиентский код, взаимодействующий с вашими классами / интерфейсами. Это, конечно, не относится к библиотекам многократного использования.

Даже статья Фила Хаака , где Уилл ссылается на это:

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

Поэтому устранение проблем управления версиями, вероятно, не является хорошим аргументом для использования базовых классов. Сохранение кода СУХОЙ, однако, может быть. Однако использование базовых классов и интерфейсов не является взаимоисключающим; Вы можете позволить своему abstract class ProductRepository реализовать IProductRepository. Однако, если вы сделаете это, разоблачение чего-либо кроме IProductRepository было бы плохой идеей.

...