设计领域模型

时间:2013-04-02 11:54:49

标签: asp.net-mvc entity-framework domain-driven-design domain-model

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

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

2 个答案:

答案 0 :(得分:1)

用抽象的术语说话很难,所以这里有一个可能有用的例子。想象一下,我们有一项服务可以让Car去旅行。在此行程中,Car可能会耗尽气体并需要换油。

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可以整体操纵汽车。汽车负责处理它的内部逻辑,例如消耗汽油和弄脏油。如果坦克中没有足够的气体,也许drive会返回实际覆盖的距离。如果它不是正常现象,它可能会引发异常。 drive方法还可以检查汽车是否已启动,是否有油,是否有气体,以及座椅是否有弯曲。启动汽车可能会以不同的速度消耗汽油。您可以看到TripService('应用程序')与CarRepository对话并操纵Car,但CarCarRepository一无所知,但仍有逻辑。

处理天然气和石油的变化可能不是TripService在现实生活中的责任,但在模拟汽车磨损的应用中,它可能会承担这些责任。

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

答案 1 :(得分:0)

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

您的模型不应该知道有关存储库的任何信息。您的存储库会使用该模型并将其保存到您的数据库中。

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

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