我对DDD有疑问。我正在构建一个学习DDD的应用程序,我有一个关于分层的问题。我有一个这样的应用程序:
UI图层调用=> 应用层 - > 域层 - > 数据库
以下是代码外观的一个小例子:
//****************UI LAYER************************
//Uses Ioc to get the service from the factory.
//This factory would be in the MyApp.Infrastructure.dll
IImplementationFactory factory = new ImplementationFactory();
//Interface and implementation for Shopping Cart service would be in MyApp.ApplicationLayer.dll
IShoppingCartService service = factory.GetImplementationFactory<IShoppingCartService>();
//This is the UI layer,
//Calling into Application Layer
//to get the shopping cart for a user.
//Interface for IShoppingCart would be in MyApp.ApplicationLayer.dll
//and implementation for IShoppingCart would be in MyApp.Model.
IShoppingCart shoppingCart = service.GetShoppingCartByUserName(userName);
//Show shopping cart information.
//For example, items bought, price, taxes..etc
...
//Pressed Purchase button, so even for when
//button is pressed.
//Uses Ioc to get the service from the factory again.
IImplementationFactory factory = new ImplementationFactory();
IShoppingCartService service = factory.GetImplementationFactory<IShoppingCartService>();
service.Purchase(shoppingCart);
//**********************Application Layer**********************
public class ShoppingCartService : IShoppingCartService
{
public IShoppingCart GetShoppingCartByUserName(string userName)
{
//Uses Ioc to get the service from the factory.
//This factory would be in the MyApp.Infrastructure.dll
IImplementationFactory factory = new ImplementationFactory();
//Interface for repository would be in MyApp.Infrastructure.dll
//but implementation would by in MyApp.Model.dll
IShoppingCartRepository repository = factory.GetImplementationFactory<IShoppingCartRepository>();
IShoppingCart shoppingCart = repository.GetShoppingCartByUserName(username);
//Do shopping cart logic like calculating taxes and stuff
//I would put these in services but not sure?
...
return shoppingCart;
}
public void Purchase(IShoppingCart shoppingCart)
{
//Do Purchase logic and calling out to repository
...
}
}
我似乎把我的大多数业务规则都放在服务而不是模型中,我不确定这是否正确? 另外,我不完全确定我的铺设是否正确?我在正确的地方有合适的部件吗?我的模型也应该离开我的域模型吗?一般来说,我是按照DDD这样做的吗?
谢谢!
答案 0 :(得分:3)
当你问
时我的模特应该离开我的域名模型吗?
我想说,如果可能的话,你应该努力避免在一个程序中的不同对象集之间来回移动数据。这样做会导致你经历大量乏味的编写很多无聊和容易出错的代码,你将拥有一组冗余的DTO对象,它们必须镜像你的域对象,你也可以从你的方法中获得更少的里程数写,因为它们只在DTO或域对象上运行。总而言之,这是非常痛苦的,并没有取得多大成就。我尝试在整个应用程序中传递一组域对象。
(这并不意味着没有你真正需要在不同的对象集之间移动数据的情况,例如在构建反腐败层时。如果不是绝对的话,不要去寻找麻烦必要的。)
至于
IShoppingCart shoppingCart = repository.GetShoppingCartByUserName(username);
//Do shopping cart logic like calculating taxes and stuff
//I would put these in services but not sure?
域驱动设计的目标之一是尝试将业务逻辑与基础架构代码分开。无论你怎么能弄清楚如何仅使用域对象进行计算,最好进入域模型,在那里你可以编写不涉及数据库的测试。我希望让服务提取域对象的聚合,然后在域对象中进行业务逻辑计算,然后让服务保存计算在域对象中带来的状态更改。
答案 1 :(得分:2)
当服务(应用程序层)仅公开域对象上的命令而不是对象本身时,DDD最有效。
在你的例子中,我将在内部创建一个像Purchase(strng productName,int quantity)这样的服务方法 从Repository获取ShoppingCart(不必在这里使用界面) 从Repository获取Product(按名称) 并致电cart.AddProduct(产品,数量)
不是,将产品添加到购物车,计算总金额,总重量或其他商业资料的业务逻辑被封装在模式中。
答案 2 :(得分:1)
域对象和服务之间应该有一个薄层用于操作域对象(Eric Evans推荐)。此对象名通常以“Manager”结尾。例如PurchaseManager或类似的。连接不同域对象(用户,购买,地址......)的所有逻辑都在此对象中。
答案 3 :(得分:0)
关于你的问题:
&#34;我似乎把我的大多数业务规则都放在服务中而不是 模型,我不确定这是否正确?&#34;
如果业务规则不访问其他资源(数据库,服务,域对象),则可以在域对象本身中拥有该规则。如果它确实访问了其他资源,那么您应该将它们放在域服务中。