Мое основное предположение заключается в том, что наиболее важным является поддержание читабельности в доменной части реализации. Поэтому:
Если у вас одно поведение и одна возможная реализация, просто не создавайте интерфейс:
открытый класс StackOverflowAnswerGenerator {}
Если у вас одно поведение и много возможных реализаций, тогда проблем нет, и вы можете просто отбросить «I» и получить:
открытый интерфейс StackOverflowAnswerGenerator {}
открытый класс StupidStackOverflowAnswerGenerator: StackOverflowAnswerGenerator {}
открытый класс RandomStackOverflowAnswerGenerator: StackOverflowAnswerGenerator {}
открытый класс GoogleSearchStackoverflowAnswerGenerator: StackOverflowAnswerGenerator {}
// ...
Настоящая проблема возникает, когда у вас есть одно поведение и одна возможная реализация, но вам нужен интерфейс для описания его поведения (например, для удобного тестирования, из-за соглашения в вашем проекте, с использованием некоторой библиотеки / фреймворка, которая обеспечивает это). ...). Возможные решения, отличные от префикса интерфейса:
a) Префикс или суффикс реализации (как указано в некоторых других ответах в этом разделе)
b) Использовать другое пространство имен для интерфейса:
namespace StackOverflowAnswerMachine.Interfaces
{
открытый интерфейс StackOverflowAnswerGenerator {}
}
namespace StackOverflowAnswerMachine
{
открытый класс StackOverflowAnswerGenerator: Interfaces.StackOverflowAnswerGenerator
{}
}
c) Используйте другое пространство имен для реализации:
namespace StackOverflowAnswerMachine
{
открытый интерфейс StackOverflowAnswerGenerator {}
}
namespace StackOverflowAnswerMachine.Implementations
{
открытый класс StackOverflowAnswerGenerator: StackOverflowAnswerMachine.StackOverflowAnswerGenerator
{}
}
В настоящее время я экспериментирую с последней возможностью. Обратите внимание, что в исходном файле реализации у вас все еще может быть «using StackOverflowAnswerMachine;» и иметь удобный доступ к объектам домена.
ОБНОВЛЕНИЕ: Несмотря на то, что я все еще думаю, что последняя возможность является самой чистой, ее недостатком является то, что, хотя "с помощью StackOverflowAnswerMachine;" дает вам доступ ко всем объектам домена, вы должны использовать префикс всех интерфейсов домена, чтобы не путать их реализации. Это может показаться чем-то не очень удобным, но в чистом дизайне обычно класс не использует много других доменных объектов, и в основном вам нужно использовать префикс только в объявлении поля и списке параметров конструктора. Итак, это моя текущая рекомендация.
Клиент функциональности домена не должен знать, использует ли он интерфейс, абстрактный класс или конкретный класс. Если им нужно это знать, то в таком проекте есть серьезная проблема, потому что в одном и том же уровне абстракции смешаны логика предметной области и инфраструктурные проблемы. Поэтому я рекомендую решения " a " или " c ".