1

根据域模型模式,我们必须对域实体也有行为。我正在使用实体框架进行数据访问。我已提取所有实体并作为部分类移至域层。现在我在域层中有另一组部分类,其行为与存储库通信。问题是存储库也引用域模型中的实体导致循环引用。

任何人都可以为此提供设计解决方案吗?

4

2 回答 2

1

很难用抽象的术语来谈论,所以这里有一个例子可能会有所帮助。想象一下,我们有一项服务可以让我们Car旅行。在此行程中,Cars 可能会用完气,需要换油。

class Car {
    private GasTank gasTank;
    private OilPan oilPan;

    double MPG = 25.0;

    void drive( int distance ) {
        gasTank.consume( distance / MPG );
        oilPan.dirty( distance / OilDirtyRate ); // Making up a term here...but Oil gets dirty
    }

    void fillUp() {
        gasTank.fillUp();
    }

    void changeOil() {
        oilPan.empty();
        oilPan.add( new Oil() );
    }
}

// These are value objects, there's no identity here
class GasTank { }  // Imagine above methods defined
class OilPan { } // more methods

class CarRepository {
    Car findByVIN( String vin ) {
        // Search Car collection or database
        return car;
    }
    boolean register( Car car ) {
        carDao.insert( car.toDTO() );
    }
    boolean update( Car car ) {
        // write to persistence, etc.
    }
}

class TripService {
    private CarRepository carRepo;

    void takeTrip( String carVin, int milesToGo ) {
        Car car = carRepo.findByVIN( carVin );
        // calculate distance
        while ( milesToGo > 0 ) {
            car.drive( 200 );
            milesToGo -= 200;
            if ( car.isOutOfGas() ) {
                car.fillUp();
            }
            if ( car.needsOilChange() ) {
                car.changeOil();
            }
        }
        carRepo.update( car );
    }
}

我很抱歉使用了另一个汽车示例(和 Java,因为您说的是 C#),但是您可以看到 Car 仍然具有逻辑,但是 TripService 可以将 Car 作为一个整体进行操作。Car 负责处理它的内部逻辑,例如消耗气体和弄脏油。drive如果油箱中没有足够的气体,可能会返回实际覆盖的距离。如果不是正常发生,它可能会引发异常。该drive方法还可以检查汽车是否已启动、是否有油、是否有气以及是否扣好座椅节拍。启动汽车可能会以不同的速度消耗汽油。您可以看到 TripService(“应用程序”)与 对话CarRepository和操作Car,但对 却Car一无所知CarRepository,但仍有逻辑。

处理汽油和机油的更换可能不是TripService现实生活中的责任,但在模拟汽车磨损的应用程序中,它可能会承担这些责任。

回到抽象术语,您的服务与存储库和工厂交互以获取域对象。然后他们在需要的地方编排域对象之间的交互。毕竟,有些东西必须告诉您的域对象该做什么。这就是服务发挥作用的地方。域对象对存储库一无所知,因为它们是持久性无知的。知道自己是如何持久化的不会影响业务逻辑,因此您无需在域对象中处理它。他们只处理业务逻辑和维护不变量。存储库必须了解域对象,因为它们正在持久化和检索它们。

于 2013-04-03T06:20:05.267 回答
0

将具有与存储库对话的行为的域层中的部分类移动到适当的服务中。

您的模型不应该对存储库有任何了解。您的存储库获取模型并将其保存到您的数据库中。

然后,您在模型之上有一个层,无论是 ASP.NET MVC 中的 WCF 服务或控制器,还是位于顶部的控制台应用程序中的 Main 方法,它组织域模型交互,然后通过存储库持久保存到数据库。

您的模型不是放置所有应用程序的地方。

于 2013-04-02T12:00:46.760 回答