Действительно хороший вопрос. Я потратил довольно много времени на размышления над такими темами.
Вы демонстрируете большую проницательность, отмечая противоречие между выразительной моделью предметной области и разделением интересов. Это очень похоже на напряжение в вопросе, который я задал о Говори, не спрашивай, и принцип единой ответственности.
Вот мой взгляд на тему.
Модель предметной области анемична, поскольку не содержит логики предметной области. Другие объекты получают и устанавливают данные, используя анемичный объект домена. То, что вы описываете, мне не кажется логикой предметной области. Может быть, но, как правило, справочные таблицы и другой технический язык - это, скорее всего, термины, которые что-то значат для нас, но не обязательно что-то для клиентов. Если это неверно, поясните, пожалуйста.
В любом случае создание и сохранение объектов предметной области не должно содержаться в самих объектах предметной области, потому что это не логика предметной области.
Итак, чтобы ответить на вопрос, нет, вам не следует вводить целую кучу недоменных объектов / концепций, таких как таблицы поиска и другие детали инфраструктуры. Это утечка одной проблемы в другую. Шаблоны Factory и Repository из Domain-Driven Design лучше всего подходят для решения этих проблем отдельно от самой модели предметной области.
Но учтите, что если у вас нет логики домена, вы получите анемичные объекты домена, то есть мешки безмозглых геттеров и сеттеров, вот как некоторые магазины заявляют, что создают уровни SOA / сервисов.
Так как же получить лучшее из обоих миров? Как сфокусировать объекты предметной области только на логике предметной области, не допуская при этом UI, построения, устойчивости и т. Д.? Я рекомендую вам использовать такой метод, как Double Dispatch, или какую-либо форму ограниченный доступ к методу.
Вот пример Double Dispatch. Скажем, у вас есть эта строка кода:
entity.saveIn(repository);
В вашем вопросе saveIn () будет иметь всевозможные знания о слое данных. Используя Double Dispatch, saveIn () делает следующее:
repository.saveEntity(this.foo, this.bar, this.baz);
А метод репозитория saveEntity () обладает всеми необходимыми знаниями о том, как сохранять на уровне данных.
В дополнение к этой настройке у вас может быть:
repository.save(entity);
который просто звонит
entity.saveIn(this);
Я перечитываю это и замечаю, что объект все еще тонкий, потому что он просто отправляет свое постоянство в репозиторий. Но в этом случае объект должен быть тонким, потому что вы не описали никакой другой логики предметной области. В этой ситуации вы могли бы сказать: «К черту Double Dispatch, дайте мне аксессуары».
И да, вы могли бы, но IMO слишком много раскрывает то, как реализована ваша сущность, и эти средства доступа отвлекают от логики предметной области. Я думаю, что единственный класс, который должен иметь методы получения и набора, - это класс, имя которого заканчивается на «Аксессор».
Я скоро закончу. Лично я не пишу свои сущности с помощью методов saveIn (), потому что я думаю, что даже простое использование метода saveIn () имеет тенденцию засорять объект домена отвлекающими факторами. Я использую либо шаблон класса друга, частный доступ к пакету, либо, возможно, Шаблон Builder.
Ладно, я готов. Как я уже сказал, я немного одержим этой темой.
person
moffdub
schedule
23.10.2008