Oop 哎呀,责任到哪里去了
我有一个名为a的类和另一个名为B的类。类a包含类B作为属性 我有商业逻辑。根据B类中某个属性的值,我必须计算a类中另一个属性的值。要进行此计算,我必须调用SOAP服务,获取一个值,然后根据B类中某个属性的值,我必须对SOAP服务返回的值进行数学计算,然后在类a中设置属性的值Oop 哎呀,责任到哪里去了,oop,design-patterns,domain-driven-design,solid-principles,ooad,Oop,Design Patterns,Domain Driven Design,Solid Principles,Ooad,我有一个名为a的类和另一个名为B的类。类a包含类B作为属性 我有商业逻辑。根据B类中某个属性的值,我必须计算a类中另一个属性的值。要进行此计算,我必须调用SOAP服务,获取一个值,然后根据B类中某个属性的值,我必须对SOAP服务返回的值进行数学计算,然后在类a中设置属性的值 public Class A{ public string Property1{get;set;} public int Property2{get;set;} public B Property3{get;se
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;}
}
伪码中的逻辑
还有如何避免这种情况?我们确实需要更多关于“这些值是什么”和“它们现在或将来是否会以任何其他方式使用”的详细信息,以便能够清楚地说出它们应该去哪里 也就是说,首先,我们可以将您的伪代码清理为:
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中,以对外部调用方隐藏逻辑。在中,ClassA
是此场景中的聚合根,并且应该是处理此逻辑的根ClassB
可以引用ClassA
;我个人更喜欢让我的关系是一种严格的、单向的关系。意思是ClassB
不知道ClassA
存在。有一些边缘的情况下,我打破了这个规则;不过不多
相反,我会用它来促进这一点。这其中有一些是在线的。基本上,逻辑将从
ClassA
和ClassB
中抽象出来。相反,域事件将处理它。事件对象将得到一条消息,其中包含对ClassA
和ClassB
的引用,对其进行处理,分配所需的值(或者更好的是,通过受控方法将它们传递给类),然后执行。这使得计算的行为更易于测试,并允许您在多个地方重用此组件。我将创建一个DDD类型的“域服务”,它通过接口依赖于SOAP服务,并以这种方式进行。很好而且可以测试,我不明白为什么它不符合OCP
应避免使域模型依赖于外部服务。@RobbyCornelissen。非常感谢。我现在已经编辑过了,在这个特定的实例中,当您试图强制执行OCP时,您在寻找什么?您是否暗示决策逻辑应该在类
A
中,但条件值(“something1”、“something2”)应该在别处声明,因为它们可能会更改?这个小系统应该在哪个轴上进行扩展?我个人认为这个逻辑属于业务逻辑之外,不是吗?域层不应该接触到soap服务imo。这也可以通过适配器模式来实现。不,我认为这里不需要任何特定模式。只是设计良好、可测试的OO。