2014-05-06 53 views
0

我想使用Specification模式在我的N-Layerd DDD应用程序中应用业务规则。 我在模式中使用了我的Application Layer也。 所以我定义我Domain以下Interface使用业务规则的规范模式重构代码

public interface ISpecification<T> 
{ 
    Expression<Func<T, bool>> Predicate { get; } 
    bool IsSatisfiedBy(T entity); 
} 

,也有一些Specification S上方的接口,实现诸如BigOrderSpecification : ISpecification<Order>SpecialOrderSpecification:ISpecification<Order>

我用下面的处理程序来处理我的订单:

public class OrderProcessCommandHandler : ICommandHandler<Order> 
{ 
    OrderCommand _command; 
    public OrderProcessCommandHandler(OrderCommand command) 
    { 
     _command = command; 
    } 
    public Handle() 
    { 
     var bigOrderSpec = new BigOrderSpecification(); 
     var specialOrderSpec = new SpecialOrderSpecification(); 
     var spec = bigOrderSpec.And(specialOrderSpec); 
     if (spec.IsSatisfiedBy(_commnand.Order)) 
      // do some things 
     else 
      throw new BusinessException("Some business rules violated.") 
    }  
} 

我认为OrderProcessCommandHandlerHandle()方法,违反

  • Tell don't ask原则,因为他从OrderBR满意的结果,然后决定做点什么。
  • Open/Close原理,因为如果我想添加另一个规范,我必须更改我的CommandHandler

    我该如何重构我的代码以防止这种违规行为?

回答

2

我不会说这违反了原则

  1. Tell don't ask原则。

    由于您告诉Handle(),您的代码遵循此原则,并且您的“逻辑”和“数据”被放置在一个单一方法中。

    如果您的do some things逻辑告诉SpecialOrderSpecification,可能会违反此规则。

  2. 打开/关闭

    您的代码如下这个原则,因为如果你想添加另外一个规范,你不能改变ICommandHandler<T>接口原理。

    如果添加另一个规范需要更改接口,则可能违反该规则。

为了遵循依赖倒置原则我建议你可以通过构造注入所有的规格(例如BigOrderSpecificationSpecialOrderSpecification)。

+2

+1。而且,如果你注入你的依赖关系(即规范),你可以在处理程序之外编写规范,并且规范组合中的更改根本不会影响处理程序类。 –