返回一个新的Object vs修改作为参数传入的对象

时间:2010-08-11 20:41:08

标签: c# java oop design-principles

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

我的直觉告诉我,这不是正确的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);
    }

6 个答案:

答案 0 :(得分:8)

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

但是,在LoadSomeObject中创建someObject并将其返回也是正确的。

此时,两种选择都是正确的。

答案 1 :(得分:1)

我不是OO大师,所以带上一粒盐。

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

  2. 在任何命令式代码(包括OO代码)中,可变状态都是完美的,它是这些范例的核心“特征”。 OTOH,不可变状态具有不可忽视的优势(我想我们在这里有一些关于该主题的问题,否则问任何FP倡导者),并且有一些不可变对象并不是特别非OO。

  3. 编辑:您也可以将读者传递给SomeObject的构造函数。

答案 2 :(得分:1)

没有通用的OO概念,这与这样的代码相冲突。 但是,如果你不遵循一些设计原则,你会发现很难收集并理解操纵SomeObject实例的方法。 也许最简单的启动方式是将两种主要程序分开:

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

这里好主意,如果你想分开SomeObject操纵逻辑就是用

创建SomeObjectBuilder类型
 public void loadFromReader( SqlDataReader reader )

方法和

  

public SomeObject getValue()

属性

答案 3 :(得分:0)

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

复制方法显然需要返回副本。其中作为单个对象的方法,例如由全局引用持有的方法,不适合返回新对象,因为更改可能会丢失。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

我认为这仍然感觉好一点(无论如何大多数情况下):

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

然后显然在SomeObject课程中你会有

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

这个想法是赞成实例方法而不是静态方法。当你可以让对象操作自己的数据时,为什么还要创建一个对象并传递它的数据呢?