域驱动设计和工厂类的作用 [英] Domain Driven Design and the role of the factory class

查看:120
本文介绍了域驱动设计和工厂类的作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不清楚工厂阶级的作用和责任是什么。我足够了解工厂类应该是可重用的,用于创建域对象(聚合根)及其关联实体和值对象。



但是什么不清楚我是DDD架构的工厂层在哪里?工厂应该直接调用存储库来获取数据或服务库吗?



工厂适合以下框架:

UI>应用>域>服务>数据



另外,因为工厂是唯一允许对象创建的地方,如果要在数据和服务层中创建对象,您是否可以获得循环引用?



如果工厂类的作用是用于创建对象,那么服务层有什么好处?



我已经问了很多问题并感谢任何回应。我缺少的是一个示例应用程序,它演示了域驱动设计项目中的所有层如何组合在一起?有没有什么?

解决方案但是我不清楚的是,
工厂层在于DDD
的架构?工厂是否要
直接拨入资料库
以获取其数据或服务
库?




工厂应该是一站式构建域对象。代码中的任何其他部分需要使用工厂。



通常,至少有三个数据来源用作工厂的输入域对象构造:从UI输入,持久性查询的结果和域有意义的请求。所以要回答你的具体问题,资料库会使用工厂。



这是一个例子。我正在使用 Holub的Builder模式这里。 编辑:忽略使用此模式。我已经意识到它没有与DDD工厂结合得太好了

  // domain layer 
class Order
{
private Integer ID;
私人客户所有者;
私人列表<产品>有序;

//不能为null,需要复杂的规则来初始化
私有产品特色;

//不能为null,需要复杂的规则来初始化,不是Order的一部分
private行程安排;

void importFrom(进口商进口商){...}

void exportTo(出口商出口商){...}

...插入业务逻辑方法在这里...

接口进口商
{
整数importID();
客户importOwner();
Product importOrdered();
}

接口导出器
{
void exportID(Integer id);
void exportOwner(客户所有者);
void exportOrdered(产品订购);
}
}

//域层
接口OrderEntryScreenExport {...}

// UI
class UIScreen
{
public UIScreen(OrderEntryDTO dto){...}
}

//应用层
类OrderEntryDTO实现OrderEntryScreenExport {...}

这是OrderFactory可能是什么样子:

 接口OrderFactory 
{
订购createWith(客户所有者,产品订购);
订单createFrom(OrderEntryScreenExport to);
订单createFrom(List< String> resultSets);
}

特色产品的逻辑和行程的生成进入OrderFactory 。



现在,这里是每个实例可以使用工厂。



在OrderRepository中:

  public List< Order> findAllMatching(Criteria someCriteria)
{
ResultSet rcds = this.db.execFindOrdersQueryWith(someCriteria.toString());
列表<列表< String>> results = convertToStringList(rcds);

列表<订单> returnList = new ArrayList< Order>();

for(List< String> row:results)
returnList.add(this.orderFactory.createFrom(row));

return returnList;
}

在您的应用层:

  public void submitOrder(OrderEntryDTO dto)
{
订单toBeSubmitted = this.orderFactory.createFrom(dto);

this.orderRepo.add(toBeSubmitted);

//做其他的东西,提高事件等
}

在您的域层内,单元测试可能是:

  Customer carl = customerRepo.findByName(Carl); 
列表<产品> weapon = productRepo.findAllByName(Ruger P-95 9mm);
订购weaponForCarl = orderFactory.createWith(卡尔,武器);

weaponForCarl.place();

assertTrue(weaponsForCarl.isPlaced());
assertTrue(weaponsForCarl.hasSpecialShippingNeeds());




工厂适合
以下框架: UI>应用>域>服务>数据


域。


另外,因为工厂是唯一的
允许对象创建的地方
不会得到循环引用
如果你想创建你的对象
您的数据和服务层?


在我的示例中,所有依赖关系从上到下流动。我使用依赖性反转原则(PDF链接),以避免您所说的问题


如果工厂类的角色是对象创建的
,那么服务层有哪些优点
?如果您的逻辑不适合任何单个域对象,或者您有一个涉及协调多个域对象的算法,使用服务。该服务将封装任何不符合任何其他规则的逻辑,并将其委托给适合的域对象。



在这个例子中,我在这里写道,我想象,提出订单的行程将涉及多个域对象。您所描述的层次结构可能应该是UI> App>域服务>域>基础设施(数据)

,可以将OrderFactory委托给这样的服务。






我问过很多问题,
感谢任何回应。我没有
是一个示例应用程序
演示了
域驱动设计项目中的所有图层是否共同
...有什么东西
那么?


域驱动设计。它有很多代码示例,虽然我不知道是否强调分层。分层可能是棘手的,几乎是与DDD不同的主题。



在Evans书中,有一个很小的分层示例,您可能需要查看。分层是企业模式,Martin Fowler撰写了企业应用程序架构模式,您可能会也很有用。


I'am unclear as to what the roles and responsibility of the factory class is. I know enough that the factory class should be resposible for the creation of domain objects (aggregate root) along with its associated entities and value objects.

But what is not clear to me is where the factory "layer" lies with a DDD architecture? Should the factory be calling directly into the repository to get its data or the service library?

Where does the factory fit into the following framework:
UI > App > Domain > Service > Data

Also, because the factory is the only place allowed for object creation would'nt you get circular references if you wanted to create your objects in your data and service layers?

If the role of the factory class is for object creation then what benefits does the service layer have?

I've asked a lot of questions and appreciate any response. What i'am lacking is a sample application which demonstrates how all the layers in a domain driven design project come together...Is there anything out there?

解决方案

But what is not clear to me is where the factory "layer" lies with a DDD architecture? Should the factory be calling directly into the repository to get its data or the service library?

The factory should be the one-stop shop to construct domain objects. Any other part of the code that needs to do this should use the factory.

Typically, there are at least three sources of data that are used as input into a factory for domain object construction: input from the UI, the results of queries from persistence, and domain-meaningful requests. So to answer your specific question, the repository would use the factory.

Here is an example. I am using Holub's Builder pattern here. Edit: disregard the use of this pattern. I've started realizing that it doesn't mix too well with DDD factories.

// 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 { ... }

Here is what the OrderFactory might look like:

interface OrderFactory
{
    Order createWith(Customer owner, Product ordered);
    Order createFrom(OrderEntryScreenExport to);
    Order createFrom(List<String> resultSets);
}

The logic for the featured Product and the generation of the Itinerary go in the OrderFactory.

Now here is how the factory might be used in each instance.

In 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;
}

In your application layer:

public void submitOrder(OrderEntryDTO dto)
{
    Order toBeSubmitted = this.orderFactory.createFrom(dto);

    this.orderRepo.add(toBeSubmitted);

    // do other stuff, raise events, etc
}

Within your domain layer, a unit test perhaps:

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());

Where does the factory fit into the following framework: UI > App > Domain > Service > Data

Domain.

Also, because the factory is the only place allowed for object creation would'nt you get circular references if you wanted to create your objects in your data and service layers?

In my example, all dependencies flow from top to bottom. I used the Dependency Inversion Principle (PDF link) to avoid the problem you speak of.

If the role of the factory class is for object creation then what benefits does the service layer have?

When you have logic that doesn't fit into any single domain object OR you have an algorithm that involves orchestrating multiple domain objects, use a service. The service would encapsulate any logic that doesn't fit in anything else and delegate to domain objects where it does fit.

In the example I scribbled here, I imagine that coming up with an Itinerary for the Order would involve multiple domain objects. The OrderFactory could delegate to such a service.

BTW, the hierarchy you described should probably be UI > App > Domain Services > Domain > Infrastructure (Data)

I've asked a lot of questions and appreciate any response. What i'am lacking is a sample application which demonstrates how all the layers in a domain driven design project come together...Is there anything out there?

Applying Domain Driven Design and Patterns by Jimmy Nilsson is a great compliment to Eric Evans' Domain-Driven Design. It has lots of code examples, though I don't know if there is an emphasis on layering. Layering can be tricky and is almost a topic separate from DDD.

In the Evans book, there is a very small example of layering you might want to check out. Layering is an enterprise pattern, and Martin Fowler wrote Patterns of Enterprise Application Architecture, which you might find useful too.

这篇关于域驱动设计和工厂类的作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆