【问题标题】:OOP - Where does the responsibility goOOP - 责任在哪里
【发布时间】:2015-09-16 17:15:21
【问题描述】:

我有一个名为 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;set;}
}

public class B{
 public string Property1{get;set;}
 public string Property2{get;set;}
}

伪代码中的逻辑

  1. 如果 classB.property1 = "Something1" 然后调用soap服务,获取一些整数值,进行一些算术计算 使用常量,并将结果分配给 classA.Property2
  2. Else If classB.property1 = "Something2" 然后调用soap服务,获取一些整数值,并将结果分配给 classA.Property2
  3. 然后将 classA.Property2 设置为默认值。

我不喜欢 If else,它不遵循 OCP。我正在考虑与装饰师一起做这件事。第二种选择是使用构建器模式并封装 if else 逻辑,但它仍然会破坏 OCP。还是可以执行此操作的全新域服务?但是,即使我选择采用域服务方式,OCP 仍然会被破坏。

上面的逻辑是在一个业务逻辑类中执行的。

那么上述计算逻辑的责任在哪里呢? 否则如何避免这种情况?

【问题讨论】:

  • @RobbyCornelissen 。谢谢你。我现在编辑了它
  • 在此特定实例中尝试强制执行 OCP 时,您在寻找什么?您是否暗示决策逻辑应该在A 类中,但条件值(“something1”、“something2”)应该在其他地方声明,因为它们可能会改变?这个小系统应该在哪个轴上开放扩展

标签: oop design-patterns domain-driven-design solid-principles ooad


【解决方案1】:

我将创建一个 DDD 类型的“域服务”,它通过一个接口依赖于 SOAP 服务并以这种方式进行。不错且可测试,但我不明白为什么它不符合 OCP。

应避免使域模型依赖于外部服务。

【讨论】:

  • 这也可以通过适配器模式来实现吗?
  • 我认为这里不需要任何特定模式。只是精心设计、可测试的 OO。
【解决方案2】:

DDD 中,ClassA 是此场景中的聚合根,应该是处理此逻辑的那个。 ClassB 可以引用ClassA;我个人更喜欢让我的关系成为一种严格的、单向的关系。意思是ClassB 知道ClassA,存在。在某些极端情况下我违反了这条规则;虽然不多。

相反,我会使用Domain events 来促进这一点。 There are 几个good examples 这个在线到look at。基本上,逻辑将从ClassAClassB 中抽象出来。相反,领域事件会处理它。事件对象将收到一条消息,其中包含对ClassAClassB 的引用,处理它,分配它需要的任何值(或者更好的是,通过受控方法将它们传递给类),然后完毕。这使得计算的行为更加可测试,并允许您在多个地方重用此组件。

【讨论】:

    【解决方案3】:

    我们确实需要更多关于“这些值是什么”和“它们现在或将来会以任何其他方式使用”的详细信息,以便能够清楚地说明它们应该去哪里。

    也就是说,首先,我们可以将您的伪代码清理为:

    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 类中,以对外部调用者隐藏逻辑。

    【讨论】:

    • 我个人认为这个逻辑属于业务逻辑之外,不是吗?域层不应该与肥皂服务 imo 联系。
    猜你喜欢
    • 1970-01-01
    • 2011-06-15
    • 2011-11-14
    • 1970-01-01
    • 1970-01-01
    • 2017-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多