在代码中重用数据协定作为对象模型的推荐模式是什么?

时间:2018-10-14 01:46:52

标签: c# .net oop design-patterns

假设我拥有一项服务并发布了一份合同,例如

public class MyObject
{
    public int Foo { get; }

    public string Bar { set; }
}

我认为在数据合同中包含“行为”是不适当的,例如

public class MyObject
{
    public int Foo { get; }

    public string Bar { set; }

    public void DoSomeAlgorithmWithMyProperties() { … }
}

换句话说,数据合同应该只是价值包。

所以我的问题是如何在这样的对象上创建行为。我可以看到的一种方法是只创建一个单独的镜像对象,例如

public class MyObjectInternal
{
    public int Foo { get; }

    public string Bar { set; }

    public class MyObjectInternal(int foo, string bar)
    {
        this.Foo = foo;
        this.Bar = bar;
    }

    public void DoSomeAlgorithmWithMyProperties() { … }
}

另一个是继承

public class MyObjectInternal : MyObject
{
    public class MyObjectInternal(int foo, string bar)
    {
        this.Foo = foo;
        this.Bar = bar;
    }

    public void DoSomeAlgorithmWithMyProperties() { … }
}

和其他可能性可能是通过具有对值进行操作的单独的类来完全分离行为和数据,例如

public static class MyObjectAlgorithmDoer
{
     public static void DoSomeAlgorithmWithMyProperties(MyObject myObject) { … }
}

2 个答案:

答案 0 :(得分:0)

我看到有两种方法可以将行为添加到MyObject合同中。一种方法是创建一个与MyObject对话的服务,如下所示:

public class MyObjectService 
{
    public void DoOperation(MyObject myObject) 
    {
    }
}
然后

MyObjectService类可以被您的应用程序调用以执行操作。

在上述方法中,您所拥有的是贫血领域模型,在该模型中,数据和对该数据的操作彼此分开。这种方法的问题在于,它可能导致代码重复,并且可能导致违反数据完整性的行为。如果您的应用程序很简单,这仍然是一个好方法。

但是,如果您的系统复杂且不断发展,那么您可以遵循Domain Driven Design。来自Wiki:

  

域驱动设计的前提如下:

     
      
  • 将项目的主要精力放在核心领域和领域逻辑上;
  •   
  • 基于领域模型的复杂设计;
  •   
  • 启动技术专家和领域专家之间的创意合作,以迭代地完善可解决的概念模型   特定领域的问题。
  •   

DDD最初可能很难遵循。我建议您在跳到解决方案之前完全理解这个概念。这是一些了解DDD的很好的参考和教程

答案 1 :(得分:0)

在您的情况下,使用继承不是正确的方法。我不明白为什么您认为继承可以帮助您?在您的情况下,使用继承是紧密耦合的,并且封装的中断(如果您有多个子类)也与抽象类相同。我认为您可能需要Domain model pattern并定义适当的值对象。我建议您阅读patterns of enterprise application这本书,在这本书中,您将介绍用于创建域模型的不同模式。