我正在使用DDD开发一个C#项目。我写了一些课。有些属于实体类别,其他属于价值对象类别。我的问题是,为了忠实于实体和价值对象的定义,我必须或者应该做多少工作?
实体:
价值对象:
这些可能性强于执行概念,但是,这些是强制性的吗?因为制作那些工厂,那些静态方法,重载和覆盖所有这些方法似乎是一个巨大的负担或少量工作,应用DDD概念。
我应该走多远?
答案 0 :(得分:4)
我喜欢一种编程原则,它被称为KISS。
最重要的是尽可能地去做,不要只是因为你已经听说过或遇到它们而做事并遵循指导方针。而是从基本功能开始,并根据需要不断添加内容。
例如,您谈到了工厂。我通常不使用它们,除非对象创建很复杂或者我想强制执行某些条件,或者当你谈到运算符重载以进行比较时,我不这样做,除非我需要在我的代码中进行实际比较或需要它。我可以应用的一件事是Immutability,而不仅仅因为它适用于Value Objects,而且因为它在多线程支持方面是一个很好的工具,因为在创建后不能修改不可变对象。 / p>
摘要:从简单开始,根据需要添加内容。
答案 1 :(得分:1)
开始简单并进化。
例如: 假设我有一个实体PendingOrder,我用它开始:
应用层:
@Transactional
@Override
public PendingOrder placeOrder(Address deliveryAddress, Date deliveryTime) {
PendingOrder pendingOrder = new PendingOrder(
pendingOrderRepository.nextTrackingId(), deliveryAddress,
deliveryTime); //by constructor
pendingOrderRepository.store(pendingOrder);
return pendingOrder;
}
稍后,当客户端需要验证是否有可用的餐厅用于交付信息时,我引入了PendingOrderFactory来强制执行一些域约束:
应用层:
@Transactional
@Override
public PendingOrder placeOrder(Address deliveryAddress, Date deliveryTime) {
PendingOrder pendingOrder = pendingOrderFactory.placeOrderWith(
deliveryAddress, deliveryTime);//refactor to factory
pendingOrderRepository.store(pendingOrder);
return pendingOrder;
}
域层:
public PendingOrder placeOrderWith(Address deliveryAddress,
Date deliveryTime) {
if (restaurantRepository.isAvailableFor(deliveryAddress, deliveryTime)) {
return new PendingOrder(pendingOrderRepository.nextTrackingId(),
deliveryAddress, deliveryTime);
} else {
throw new NoAvailableRestaurantException(deliveryAddress,
deliveryTime);
}
}
另一方面,可以使用一些代码生成工具。这是我们在java中使用的
@ToString(of = "trackingId") //print PendingOrder.trackingId
@EqualsAndHashCode(of = "trackingId")//compare trackingId when Equals
public class PendingOrder {// this is an entity
@ToString //print all fields
@EqualsAndHashCode //compare all fields
@NoArgsConstructor
// @NoArgsConstructor for frameworks only
public class Address {// this is a value object
然而,我们只在必要时添加它们,通常,当您编写测试报告explict错误时需要@ToString,当您使用模拟编写测试时需要@EqualsAndHashCode。
例如:pendingOrderFactory是一个模拟器,我们验证它是用给定的参数(deliveryAddress,deliveryTime)调用的,模拟框架用Equals检查它,当我们不满足expecation时,会显示一个报告。模拟框架调用ToString来指示哪个对象打破了expecation。
@Test
public void placesAPendingOrder() throws Exception {
final PendingOrder pendingOrder = new PendingOrderFixture().build();
final Address deliveryAddress = pendingOrder.getDeliveryAddress();
final Date deliveryTime = pendingOrder.getDeliveryTime();
context.checking(new Expectations() {
{
allowing(pendingOrderFactory).placeOrderWith(deliveryAddress,
deliveryTime);//need to implement equals
will(returnValue(pendingOrder));
oneOf(pendingOrderRepository).store(pendingOrder);//need to implement equals
}
});
PendingOrder order = target.placeOrder(deliveryAddress, deliveryTime);
assertThat(order, is(pendingOrder));
}
希望这对Java示例有帮助和抱歉'因为我是C#白痴:(