7

在代码审查期间,我遇到了以下代码。

我的直觉告诉我,这没有遵循正确的 OOP。

我认为 LoadObject 方法应该返回一个新的 SomeObject 对象,而不是修改传递给它的对象。虽然我真的找不到一个正确的解释为什么这更好。

我的解决方案更好吗?如果是这样,为什么?具体来说,在给定的代码示例(如果有)中违反了哪些 OOP 原则或标准?

   public void someMethod()
    {
        ...
        var someObject = new SomeObject();
        LoadSomeObject(reader,someObject);
    }

    private void LoadSomeObject(SqlDataReader reader, SomeObject someObject)
    {
       someObject.Id = reader.GetGuid(0);
    }
4

6 回答 6

8

编写代码的方式没有任何问题,因为您只是在修改 someObject 上的属性。

但是,在 LoadSomeObject 中创建 someObject 并返回它同样正确。

在这一点上,两种选择都一样正确。

于 2010-08-11T20:46:55.133 回答
2

我不是 OO 专家,所以对这些持保留态度。

  1. 对象应该尽可能自己管理/定义自己的行为。如果您曾经是松散耦合的负责人,那么这背后的基本原理是显而易见的。将细节转移到 SomeObject 的实现中,我很可能是更好的设计决策LoadSomeObject,但是对于这样一个一般示例来说,这很难讨论。

  2. 可变状态在任何命令式代码(包括 OO 代码)中都很好,它是这些范例的核心“特性”。OTOH,不可变状态具有无法定义的优势(我想我们在这里对此主题有几个问题,否则请询问任何 FP 拥护者),并且拥有一些不可变对象并不是特别非 OO。

编辑:您也可以将 reader 传递给 SomeObject 的构造函数。

于 2010-08-11T20:49:48.690 回答
1

没有通用的 OO 概念,这与这样的代码相冲突。但是后来你会发现如果你不遵循一些设计原则,你会发现很难收集和理解操纵 SomeObject 实例的方法。对于初学者来说,最简单的方法可能是分离两种主要的程序:

  • 功能 - 旨在创建新实例而不是改变其他对象。
  • 有条不紊 - 旨在更改其主机实例的状态。

这里好主意,如果你想分离 SomeObject 操作逻辑是创建 SomeObjectBuilder 类型

 public void loadFromReader( SqlDataReader reader )

方法和

公共 SomeObject getValue()

财产

于 2010-08-12T00:36:24.497 回答
0

无论哪种方式都是完全可以接受的,但是在决定哪种方式适合您的特定情况时,要考虑您希望如何处理返回的对象。不变性,即在每个操作中创建一个新实例是 .NET 中字符串的处理方式。

复制方法显然需要返回一个副本。例如,在单例对象上工作的方法不适合返回新对象,因为更改可能会丢失。

于 2010-08-11T20:55:34.113 回答
0

如果LoadSomeObject要返回一个新的SomeObject,您可能需要更改方法名称以避免混淆。也许到NewAndLoadSomeObject

于 2010-08-11T21:06:42.547 回答
0

我同意你的直觉,在大多数情况下感觉有点不对劲。我同意返回一些东西会更好,因为它只是更清楚地表明正在修改某些东西。看到正在使用的返回值可以立即清楚发生了什么。

不过,我认为这感觉还是好一些(在大多数情况下):

public void someMethod()
{
    ...
    var someObject = new SomeObject();
    someObject.Load(reader);
}

然后显然在SomeObject课堂上,你会有

public void Load(SqlDataReader reader)
{
   this.Id = reader.GetGuid(0);
}

这个想法是支持实例方法而不是静态方法。当您可以让对象对自己的数据进行操作时,为什么还要费心创建对象并传递其数据呢?

于 2010-08-12T00:07:27.010 回答