Интерфейс говорит, как что-то должно работать. Думайте об этом как о контракте или шаблоне. Это ключ к таким вещам, как Inverson of Control или Depenancy Injection.
Я использую Карту структуры в качестве контейнера IoC. Это позволяет мне определить интерфейс для всех моих классов. Где вы могли бы сказать
Widget w = new Widget();
Я бы сказал
IWidget w = ObjectFactory.GetInstance<IWidget>();
Это очень мощно, потому что мой код не обязательно говорит, что такое Widget. Он просто знает, что может делать виджет на основе интерфейса IWidget.
Это имеет большую силу в том, что теперь, когда я использую контейнер IoC, я могу сделать еще пару изящных вещей. В моих модульных тестах, где мне нужно использовать виджет, я могу создать макет для виджета. Итак, скажем, что мой Widget делает что-то очень мощное, подключаясь к базе данных или веб-службе, мой макет может симулировать подключение к этим ресурсам и возвращать мне заглушки. Это ускоряет мой тест и ведет себя более надежно. Поскольку я использую StructureMap, я могу сказать StructureMap загрузить реальную реализацию моего виджета во время производственного использования моего кода и проверенной версии виджета во время тестирования либо программно, либо по конфигурации.
Кроме того, поскольку я использую контейнер IoC, я могу предоставить в приложение новые интересные функции, такие как написание трех различных способов кэширования данных. Я могу иметь локальный кеш разработчика, используя такой инструмент, как Lucene.NET для локального кэша. У меня может быть сервер разработки, использующий кеш .NET, который отлично работает на одном компьютере. И тогда у меня может быть третий вариант для моих производственных серверов, использующих слой кеша, такой как MemCache Win32 или Velocity. Пока все три реализации кэширования соответствуют одному и тому же интерфейсу, их фактическая реализация не касается меня (или моего кода) вообще. Я просто прошу StructureMap перейти к реализации текущей среды, а затем приступить к работе.
Если вы вообще следуете Dependency Injection, то здесь вам пригодятся интерфейсы с контейнером IoC, таким как StructureMap, в котором я могу объявить использование класса через интерфейс в конструкторе моего класса.
public class Widget(IWidgetRepository repository, IWidgetService service) : IWidget
{
//do something here using my repository and service
}
А потом, когда я создаю экземпляр Widget с помощью StructureMap, например,
IWidget widget = ObjectFactory.GetInstance<IWidget>();
Обратите внимание, что я не указываю хранилище или службу в конструкторе. Благодаря интерфейсам, указанным в конструкторе, StructureMap знает, как получить соответствующие экземпляры и передать их тоже. Это делает очень мощный и чистый код!
Все из простого определения интерфейсов и их умного использования!