Но что мне не понятно, это где
заводской «слой» лежит с DDD
архитектура? Должна ли фабрика быть
вызывая прямо в хранилище
чтобы получить свои данные или услугу
библиотека
Фабрика должна быть универсальной, чтобы создавать доменные объекты. Любая другая часть кода, которая должна сделать это, должна использовать фабрику.
Как правило, существует по крайней мере три источника данных, которые используются в качестве входных данных для фабрики для построения объекта домена: входные данные из пользовательского интерфейса, результаты запросов из постоянства и значимые для домена запросы. Поэтому, чтобы ответить на ваш конкретный вопрос, хранилище будет использовать фабрику.
Вот пример. Я использую паттерн Holub's Builder здесь. Редактировать : игнорировать использование этого шаблона. Я начал понимать, что не слишком хорошо сочетается с фабриками DDD .
// domain layer
class Order
{
private Integer ID;
private Customer owner;
private List<Product> ordered;
// can't be null, needs complicated rules to initialize
private Product featured;
// can't be null, needs complicated rules to initialize, not part of Order aggregate
private Itinerary schedule;
void importFrom(Importer importer) { ... }
void exportTo(Exporter exporter) { ... }
... insert business logic methods here ...
interface Importer
{
Integer importID();
Customer importOwner();
Product importOrdered();
}
interface Exporter
{
void exportID(Integer id);
void exportOwner(Customer owner);
void exportOrdered(Product ordered);
}
}
// domain layer
interface OrderEntryScreenExport { ... }
// UI
class UIScreen
{
public UIScreen(OrderEntryDTO dto) { ... }
}
// App Layer
class OrderEntryDTO implements OrderEntryScreenExport { ... }
Вот как может выглядеть OrderFactory:
interface OrderFactory
{
Order createWith(Customer owner, Product ordered);
Order createFrom(OrderEntryScreenExport to);
Order createFrom(List<String> resultSets);
}
Логика выбранного Продукта и создание Маршрута идут в OrderFactory.
Теперь вот как фабрика может использоваться в каждом случае.
В OrderRepository:
public List<Order> findAllMatching(Criteria someCriteria)
{
ResultSet rcds = this.db.execFindOrdersQueryWith(someCriteria.toString());
List<List<String>> results = convertToStringList(rcds);
List<Order> returnList = new ArrayList<Order>();
for(List<String> row : results)
returnList.add(this.orderFactory.createFrom(row));
return returnList;
}
На вашем прикладном уровне:
public void submitOrder(OrderEntryDTO dto)
{
Order toBeSubmitted = this.orderFactory.createFrom(dto);
this.orderRepo.add(toBeSubmitted);
// do other stuff, raise events, etc
}
В вашем доменном слое возможно модульное тестирование:
Customer carl = customerRepo.findByName("Carl");
List<Product> weapons = productRepo.findAllByName("Ruger P-95 9mm");
Order weaponsForCarl = orderFactory.createWith(carl, weapons);
weaponsForCarl.place();
assertTrue(weaponsForCarl.isPlaced());
assertTrue(weaponsForCarl.hasSpecialShippingNeeds());
Где фабрика вписывается в
следующая структура: UI> Приложение> Домен> Сервис> Данные
Домен.
Кроме того, потому что фабрика является единственным
место разрешено для создания объекта
не могли бы вы получить циркулярные ссылки
если вы хотите создать свои объекты
в ваших слоях данных и обслуживания?
В моем примере все зависимости текут сверху вниз. Я использовал принцип инверсии зависимостей (ссылка PDF), чтобы избежать проблемы, о которой вы говорите.
Если роль фабричного класса
для создания объекта, то какие преимущества
сервисный уровень имеет?
Если у вас есть логика, которая не вписывается ни в один объект домена, ИЛИ у вас есть алгоритм, который включает в себя организацию нескольких объектов домена, используйте службу. Служба будет инкапсулировать любую логику, которая не подходит ни для чего другого, и делегировать объектам домена там, где она подходит.
В примере, который я написал здесь, я представляю, что разработка Маршрута для Ордена будет включать несколько доменных объектов. OrderFactory может делегировать такую услугу.
Кстати, иерархия, которую вы описали, вероятно, должна быть UI> Приложение> Доменные службы> Домен> Инфраструктура (Данные)
Я задавал много вопросов и
ценим любой ответ. Что я
отсутствует пример приложения, которое
демонстрирует, как все слои в
доменный дизайн-проект
вместе ... Есть что-нибудь
есть
Применение доменного дизайна и шаблонов от Джимми Нильссона является отличным дополнением к доменному дизайну Эрика Эванса . В нем много примеров кода, хотя я не знаю, стоит ли делать акцент на многоуровневую структуру Расслоение может быть сложным и является почти темой, отдельной от DDD.
В книге Эванса есть очень маленький пример наслоения, который вы, возможно, захотите проверить. Многоуровневая структура - это корпоративный шаблон, и Мартин Фаулер написал Шаблоны архитектуры корпоративных приложений , что также может оказаться полезным.