Я не понимаю интерфейсы? - PullRequest
       1

Я не понимаю интерфейсы?

6 голосов
/ 09 декабря 2011

Я поддерживаю проект ASP.NET MVC.В проекте оригинального разработчика есть абсолютная тонна интерфейсов.Например: IOrderService, IPaymentService, IEmailService, IResourceService.Что меня смущает, так это то, что каждый из них реализуется только одним классом.Другими словами:

OrderService : IOrderService
PaymentService : IPaymentService

Мое понимание интерфейсов всегда заключалось в том, что они используются для создания архитектуры, в которой компоненты можно легко заменять.Что-то вроде:

Square : IShape
Circle : IShape

Кроме того, я не понимаю, как они создаются и используются.Вот OrderService:

public class OrderService : IOrderService
{
    private readonly ICommunicationService _communicationService;
    private readonly ILogger _logger;
    private readonly IRepository<Product> _productRepository;

    public OrderService(ICommunicationService communicationService, ILogger logger,
        IRepository<Product> productRepository)
    {
        _communicationService = communicationService;
        _logger = logger;
        _productRepository = productRepository;
    }
}

Эти объекты, кажется, никогда не создаются напрямую, как в OrderService orderService = new OrderService(), он всегда использует интерфейс.Я не понимаю, почему интерфейсы используются вместо класса, реализующего интерфейс, или как это вообще работает.Есть ли что-то важное, что мне не хватает в интерфейсах, которые не раскрываются моими навыками Google?

Ответы [ 5 ]

4 голосов
/ 09 декабря 2011

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

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

Что касаетсяпочему вы никогда не видите в коде «новый OrderService», вполне вероятно, что ваш проект использует некоторую форму контейнера Inversion of Control, что облегчает автоматическое внедрение зависимостей.Другими словами, вам не нужно создавать OrderService напрямую, потому что где-то вы настроили, что любое использование IOrderService должно автоматически выполняться путем создания одиночного OrderService и передачи его конструктору.Здесь много тонкостей, и я не совсем уверен, как выполняется внедрение зависимости (это не обязательно должно быть автоматически; вы также можете просто создать экземпляры вручную и передать их через конструкторы.)

1 голос
/ 09 декабря 2011

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

То, что в настоящее время существует только 1 класс, реализующий интерфейс, не означаетчто это не может измениться в будущем.

Кроме того, я не понимаю, как они создаются и используются.

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

1 голос
/ 09 декабря 2011

Эти объекты, кажется, никогда не создаются напрямую, как в OrderService orderService = new OrderService ()

Так что?

Дело в том, что SOMEONE вызывает конструктор OrderService, и THE CALLER отвечает за их создание. Он передает их.

Я не понимаю, почему интерфейсы используются вместо класса, реализующего интерфейс

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

Есть ли что-то важное, что мне не хватает в интерфейсах, которых нет в моих навыках Google? обнажения?

Нет, но хорошая книга о ОО-программировании поможет больше, чем случайные фрагменты Google. Это относится к области архитектуры и основам .NET (для первой части).

1 голос
/ 09 декабря 2011

Это не единственное использование интерфейсов, в MVC они используются для отделения контракта от реализации. Чтобы понять, что такое MVC, вам нужно немного прочитать о смежных темах, таких как разделение интересов и инверсия управления (IoC). Фактический акт создания объекта, передаваемого в конструктор OrderService, обрабатывается контейнером IoC на основе некоторое предопределенное отображение.

0 голосов
/ 09 декабря 2011

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

Например, если ваша платежная служба связывается с PayPal для проверки платежей, вы нене хочу делать это в тесте несвязанного кода.Вместо этого вы можете заменить их простой реализацией, которая всегда возвращает «платеж обработан», и проверить, что процесс заказа завершен, и другой реализацией, которая возвращает «платеж не выполнен», и проверить, что процесс заказа тоже не прошел.

Комуизбегайте зависимости от реализации, вы сами не создаете экземпляры, вы принимаете их в конструкторе.Затем контейнер IoC, который создает ваш класс, заполнит их. Поиск Инверсия управления .

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

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