我的系统中是否应该有一个或多个XXXRepository实例,使用DDD?

时间:2013-08-25 18:01:50

标签: oop domain-driven-design

有些东西一直困扰着我的DDD读数。从我所看到的情况来看,似乎我的系统中每个给定的聚合根类型只有一个存储库实例。

例如,考虑以下想象的情况作为更深层域模型的抽象:

enter image description here

当以“标准风格”编码时,我会认为我系统中的每个Owner都有自己的汽车集合,因此会有相同数量的Car集合(应该我称之为存储库?),因为有Owner个。但是,如前所述,似乎在DDD中我应该只在整个系统中有一个 CarRepository(我已经看过将它们作为静态类访问的示例),以及要做一些简单的操作,例如将汽车添加到Owner,我应该使用域服务,对于简单的情况,这似乎不太适合API。

我是否正确只在我的系统中实例化一个CarRepository(Singleton),或者我错过了什么?我想争取像

这样的东西
public void an_owner_has_cars() throws Exception {
    Owner owner = new Owner(new OwnerId(1));
    CarId carId = new CarId(1);
    Car car = new Car(carId);
    owner.addCar(car);
    Assert.assertEquals(car, owner.getCarOf(carId));
}

但如果没有将存储库注入Owner,这似乎是不可能的,这似乎是一种被禁止的东西。

2 个答案:

答案 0 :(得分:2)

存储库不代表属于另一个实体的集合。我们的想法是它代表整个实体集合。

因此,在您的示例中,Car是一个实体,可能是一个聚合。所以你的模型在概念层面上是可以的,但你需要在CarOwner之间分开紧密耦合,因为Owner绝对是AR,在你当前的模型中,删除它会意味着所有属于它的汽车也应该被删除。

你可能会追求的是:

public class Owner {
    private IEnumerable<OwnedCar> cars;
}

public class OwnedCar {
    public Guid CarId { get; set; }
}

或者,作为VO的替代方案:

public class Owner {
    private IEnumerable<Guid> carsOwned;
}

因此,一个AR不应该引用另一个AR实例。

另一点是你可能不想将存储库注入实体,因为这可能表明存在一些设计缺陷(有些代码味道)。

让拥有的汽车进入所有者将是OwnerRepository的工作,因为它是同一聚合的一部分。由于它是一个值对象,因此不会有OwnedCarRepository

答案 1 :(得分:1)

100%肯定,除非您在不使用任何依赖性不当机制的遗留系统中工作,否则您不必创建单个CarRepository。

如果您发现需要向所有者注入CarRepository以检索属于特定所有者的汽车,也许这是一个提示,您应该重新建模关系,如:

public class Owner {

}

public class Car {
    private Owner owner;
}

使用CareRepository实现目标:

public interface CarRepository {
    List<Car> findBy(String onwer);
}

只是一个推测,静态部分可能引用DomainEvents,如:

public class Owner {

    public long quantityOfCarsOwned() {
        return DomainEvents.raise(new SumCarsEvent(this));//static 
    }
}

public class SumCarsEventHandler {
     private CarRepository carRepository;//inject this, SumCarsEventHandler should be a statless bean managed by container like spring

     public long handle(SumCarsEvent event) {
         return carRepository.countBy(event.getOwner());
     }

}

在非常简单的情况下,我认为这太复杂了。