Я чувствую, что это объекты домена (а не объекты объектов, поскольку это название подразумевает что-то делать с базой данных) не должны быть интерфейсами, если у вас нет очень веских оснований полагать, что вам нужно будет поддерживать несколько реализации в какой-то момент в будущем.
Считайте, что модель домена - это человеческая модель. Бизнес/сервис/документ - это буквально домен. Большинство из нас разрабатывает программное обеспечение для одного бизнеса или цели. Если модель домена изменяется, это связано с изменением бизнес-правил, и, следовательно, старая модель домена уже недействительна - нет причин держать старый, работая рядом с новым.
Дискуссия, очевидно, не является черно-белой. Возможно, вы разрабатываете программное обеспечение, которое сильно настраивается на нескольких клиентских сайтах. Возможно, вам действительно понадобится реализовать разные наборы бизнес-правил одновременно и одновременно иметь настоящую необходимость встраивать их в единую архитектуру. Но, по крайней мере, по моему опыту, эти случаи являются скорее исключением, чем правилом, и хотя я вообще не люблю этот термин, это может быть случай, когда вы должны думать о себе, YAGNI.
Доступ к данным - это общая область, где вам нужны лучшие абстракции (persistence ignorance). В вашем примере у вас есть атрибуты NHibernate в вашем классе модели. Но добавление атрибутов persistence делает его уже не истинным классом домена, потому что он вводит зависимость от NHibernate. NHibernate и Fluent NHibernate поддерживают сопоставление POCOs с использованием объявления внешнего сопоставления вместо атрибутов в классе данных, и это, как правило, является предпочтительным подходом при использовании ORM, таких как NHibernate или EF4, поскольку это нарушает зависимость между моделью устойчивости и моделью домена.
Если эти методы сопоставления не поддерживаются, и вы должны использовать для использования атрибутов, тогда я бы действительно предложил использовать интерфейсы вместо этого, но сегодня ORM являются более сложными, используя рефлексию и динамические прокси и метод перехвата большая часть тяжелого подъема, поэтому вам не нужно создавать свои собственные абстракции.
Некоторые типы объектов, которые вы бы хотят выставить в качестве интерфейсов:
- Хранилища, которые несут ответственность за сохранение/загрузка объектов домена;
- Плагины/расширения вашей программы;
- Модели просмотра/презентатора, так что могут быть подключены различные интерфейсные модули;
- Абстрактные типы данных со многими реализациями (массив, список, словарь, набор записей и таблица данных - это все последовательности AKA
IEnumerable
);
- Абстрактные операции со многими возможными алгоритмами (сортировка, поиск, сравнение);
- Коммуникационные модели (такие же операции над TCP/IP, именованные каналы, RS-232);
- Что-нибудь конкретное для платформы, если вы планируете развернуть более одного (Mac/Windows/* nix).
Это отнюдь не полный список, но он должен осветить основной принцип здесь, который является то, что вещи лучше всего подходят для взаимодействия абстракций являются вещами, которые:
- зависит от факторов, которые, вероятно, вне вашего контроля;
- Скорее всего, это изменится в будущем; и
- Горизонтальные функции (используемые во многих частях приложения/архитектуры).
Класс домена будет широко использоваться, но не вписывается ни в одну из двух первых категорий; он вряд ли изменится, и вы почти полностью контролируете дизайн. Поэтому, если сами классы не будут использовать косвенные зависимости (это ситуация, которую вы должны стараться избегать, когда это возможно), я бы не стал прилагать дополнительные усилия для создания интерфейса для каждого класса в модели домена.
@Aaronaught: Ok для ORM specific, теперь предположим, что я использую FullText Features, я буду использовать Lucene.NET, которые также используют атрибуты. И насколько я знаю, нет способа использовать внешнее сопоставление атрибутов, например FluentNhibernate. Итак, каков наилучший подход для того, чтобы мои объекты домена были истинными POCOs? Может быть, интерфейсы работают таким образом? –
@Yoann. B: Я не знал, что Lucene.NET использовал атрибуты декоратора; это определенно не требует их. Если вы хотите использовать их, то у вас есть два варианта: либо (a) сделать вашу модель домена зависимой от Lucene.NET, которая кажется плохой идеей (что, если вы хотите использовать SQL FTS вместо? Что, если будущая версия Lucene.NET поддерживает POCOs?) Или (b) перемещает ваши объекты поиска и репозитории в другое пространство имен/сборку и использует такой инструмент, как AutoMapper, для преобразования их в объекты домена. В любом случае, я не думаю, что создание интерфейсов для объектов очень помогло бы. – Aaronaught
@Aaronaught: Вы сказали, что Lucene.NET не требует атрибутов? о другом вопросе, который я разместил (http://stackoverflow.com/questions/2356593/lucene-net-and-poco-entities), но как вы обходитесь без использования атрибутов с Lucene.NET? –