我有一个名为A的类和另一个名为B的类.A类包含B类作为属性。
我有一个业务逻辑。基于B类中的属性值,我必须计算A类中另一个属性的值。要进行此计算,我必须调用SOAP服务,获取值然后根据属性的值在B类中,我必须对SOAP服务的返回值进行数学计算,然后在A类中设置property的值。
public Class A{
public string Property1{get;set;}
public int Property2{get;set;}
public B Property3{get;set;}
}
public class B{
public string Property1{get;set;}
public string Property2{get;set;}
}
伪代码中的逻辑
我不喜欢If else,它不遵循OCP。我想与装饰师这样做。第二个选项是使用构建器模式并封装if else逻辑,但它仍会破坏OCP。或者是一个可以执行此操作的全新域服务?但是,如果其他人选择采用域服务方式,那么OCP仍然会被破坏。
上述逻辑正在业务逻辑类中执行。
那么上述计算逻辑的责任在哪里呢? 如果还有其他如何避免呢?
答案 0 :(得分:1)
在DDD中,ClassA
是此方案中的聚合根,应该是处理此逻辑的根。 ClassB
可以引用ClassA
;我个人更喜欢让我的关系成为一种严格的,单向的关系。含义ClassB
不会知道ClassA
存在。有一些边缘情况我违反了这个规则;虽然不是很多。
相反,我会使用Domain events来促进这一点。 There are good examples在线look at Form Elements here。基本上,逻辑将从ClassA
和ClassB
中抽象出来。相反,域事件会处理它。事件对象将被赋予一条消息,其中包含对ClassA
和ClassB
的引用,处理它,分配它需要的值(或者更好的是,通过受控方法将它们传递给类),并完成。这使计算的行为更加可测试,并允许您在多个位置重用此组件。
答案 1 :(得分:1)
我会创建一个DDD类型的“域服务”,它通过接口依赖SOAP服务并以这种方式执行。很好,可测试,我不明白为什么它不符合OCP标准。
应避免使域模型依赖于外部服务。
答案 2 :(得分:0)
我们真的需要更多关于这些价值的详细信息"并且"它们现在或将来会以任何其他方式使用"能干净利落地告诉他们应该去哪里。
那就是说,首先,我们可以将您的伪代码清理为:
Get a value from Class B.
If that value is equal to "foo":
call SOAP service
do math
assign value to property2
Else if it's equal to "bar":
call SOAP service
assign value to property2
Else
assign default value to property2
如果没有其他人从B类调用此值,并且没有其他调用从您的代码到SOAP服务,则此功能应该在B类中,以隐藏外部逻辑呼叫者。