域驱动设计 – 在域驱动设计中正确使用规范类

域驱动设计 – 在域驱动设计中正确使用规范类,第1张

概述我正在使用DDD构建一个应用程序,但是我很难理解你应该在哪里实例化规范类或使用它们. 我的应用程序大量使用预订窗口,所以我有一个规范,确保即将添加到聚合的预订窗口不会与当前聚合的另一个窗口重叠.如下所示. /// <summary>/// A specification that determines if the window passed in collides with other win 我正在使用DDD构建一个应用程序,但是我很难理解你应该在哪里实例化规范类或使用它们.

我的应用程序大量使用预订窗口,所以我有一个规范,确保即将添加到聚合的预订窗口不会与当前聚合的另一个窗口重叠.如下所示.

/// <summary>/// A specification that determines if the window passed in collIDes with other windows./// </summary>public class BookingTemplateWindowDoesNotCollIDeSpecification : ISpecification<BookingScheduleTemplateWindow>{    /// <summary>    /// The other windows to check the passed in window against.    /// </summary>    private Readonly IEnumerable<BookingScheduleTemplateWindow> otherwindows;    /// <summary>    /// Initializes a new instance of the <see cref="BookingTemplateWindowDoesNotCollIDeSpecification" /> class.    /// </summary>    /// <param name="otherwindows">The other windows.</param>    public BookingTemplateWindowDoesNotCollIDeSpecification(IEnumerable<BookingScheduleTemplateWindow> otherwindows)    {        this.otherwindows = otherwindows;    }    /// <summary>    /// Determines whether the window passed in collIDes with other windows held insIDe this class.    /// </summary>    /// <param name="obj">The obj.</param>    /// <returns>    ///  <c>true</c> if [is satisfIEd by] [the specifIEd obj]; otherwise,<c>false</c>.    /// </returns>    public bool IsSatisfIEdBy(BookingScheduleTemplateWindow obj)    {        return !this.otherwindows.Any(w => obj.DayOfWeek == w.DayOfWeek && w.WindowPeriod.IsOverlap(obj.WindowPeriod));    }}

然后我在聚合上有一个方法,允许使用规范添加一个新窗口.已经持久化的聚合窗口被传递到规范构造函数中.

public virtual voID AdDWindow(DayOfWeek dayOfWeek,int startTime,int endTime)    {        var nonCollIDingwindowspecification = new BookingTemplateWindowDoesNotCollIDeSpecification(this.windows);        var bookingWindow = new BookingScheduleTemplateWindow(this){                                                                       DayOfWeek = dayOfWeek,WindowPeriod = new Range<int>(startTime,endTime)                                                                   };        if (nonCollIDingwindowspecification.IsSatisfIEdBy(bookingWindow))        {            this.windows.Add(bookingWindow);        }    }

我正在努力的是,我的一部分是认为我应该将这个规范注入到类中而不是直接实例化(作为我的应用程序的一般规则,而不仅仅是在这种情况下),因为可能需要这种类型的specfication根据实体的状态进行更改.但是从MVC层注入规范感觉很脏,好像我有一个像REST API这样的另一个应用程序接口,然后关于使用哪个规范的逻辑将被复​​制.

如何确保所使用的规范保持灵活性,同时确保使用哪个规范的逻辑不会在另一个应用程序界面中重复.

这是一种情况,您希望将工厂注入实体并从那里返回规范,从而不允许域逻辑溢出到更高层?或者有更好/更清洁/更简单的方法吗?

解决方法 将域服务注入实体是完全可以接受的.最好将服务的依赖关系显式化为聚合中相应方法中的参数.例如,AdDWindow方法可能如下所示:

public virtual voID AdDWindow(ISpecification<BookingScheduleTemplateWindow> nonCollIDingwindowspecification,DayOfWeek dayOfWeek,int endTime)  {        var bookingWindow = new BookingScheduleTemplateWindow(this){                                                                       DayOfWeek = dayOfWeek,endTime)                                                                   };        if (nonCollIDingwindowspecification.IsSatisfIEdBy(bookingWindow))        {            this.windows.Add(bookingWindow);        }    }

在这种情况下,规范充当域服务.现在,周围的基础设施需要通过适当的规范.这就是应用程序服务的用武之地.应用程序服务在您的域层上建立了一个外观,并包含特定用例的方法.反过来,该应用程序服务将由控制器引用.控制器也可以传递所需的依赖关系,但是应用程序服务提供的封装可能是有益的.

示例应用服务代码:

public class AdDWindow(string aggregateID,int endTime){    var aggregate = this.repository.Get(aggregateID);    var specification = // instantiate specification    aggregate.AdDWindow(specification,dayOfWeek,startTime,endTime);    this.repository.Commit();}

这是典型的应用程序服务代码:获取适当的聚合,实例化所需的依赖项(如果有),并在聚合上调用行为.

总结

以上是内存溢出为你收集整理的域驱动设计 – 在域驱动设计中正确使用规范类全部内容,希望文章能够帮你解决域驱动设计 – 在域驱动设计中正确使用规范类所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1059275.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存