2013-01-31 120 views
4

我想知道以下哪种模式被认为是更“正确”的。类方法:以私有方法传递私有数据字段

第一个示例通过调用一个隐式接受参数的void成员函数来设置私有数据成员长度的值。 第二个示例通过将其分配给显式接受参数的成员函数的返回值来设置长度的值。

看起来,第二种方法使代码更清晰,因为您知道私有成员何时以及如何设置, 第一种方法需要跟踪代码来验证指定值的方式和方式。第二种方法 也似乎可以更好地重用,因为它可以在任何类/上下文中运行(因为参数和返回类型是显式的)。

第一种方法更快,如果在整个班级中使用(用于私人成员功能)可以节省一些编码,但是我不知道这是否会让我受到影响?

谢谢你的洞察力并为我解决这个问题。

class MyDataType 
{ 
    private int length; 
    private string content; 
    private char[] buffer; 

    public MyDataType(str) 
    { 
     content = str; 

     calculateLength(); 

     buffer = new char[length+1]; 

     for(int i=0; i < length; i++) 
     buffer[i] = content[i]; 

     buffer[i] = NULL; 
    } 

    private void calculateLength() 
    { 
     int i = 0; 

     while(content[i++] != NULL) {} // i know, buffer overflow... 

     length = i; 
    } 
} 

class MyDataType 
{ 
    private int length; 
    private string content; 
    private char[] buffer; 

    public MyDataType(str) 
    { 
     content = str; 

     length = calculateLength(content); 

     buffer = new char[length+1]; 

     for(int i=0; i < length; i++) 
     buffer[i] = content[i]; 

     buffer[i] = NULL; 
    } 

    private int calculateLength(string s) 
    { 
     int i = 0; 

     while(s[i++] != NULL) {} 

     return i; 
    } 
} 
+0

为什么第二个方法在第二个例子中不是静态的,即似乎没有使用类中的任何其他变量? – KingCronus

+0

这仅仅是我为了争辩而鞭挞的一个例子。所以,通过问我是否静态(这是,我想这可能是),你是否暗示第一个例子是正确的?只是B/C方法可能是静态的,应该是? – samosaris

+0

在你的第一个例子中,你有getLength方法设置私有成员变量并且不返回任何东西。通常getX方法应该返回X.也许它应该被重命名。 – Tom

回答

2

就可读性和灵活性而言,第二个例子胜出。

使用第二个示例的好处是,您基本上只是将构造函数中的一些工作委托给方法。如果有人调用私有calculateLength()方法而不希望实例变量发生变化,这很容易阅读,并且在将来不会轻易破解。

在第一个示例中,calculateLength()方法正在以不透明的方式对构造函数对成员变量进行操作,这使得它的可读性更低,并且更容易因上述方式而变得脆弱。

+0

最近这种情况经常出现,而且很急,我一直在用例子的格式。它只是看起来错误和肮脏。不过,我想在这里得到普遍的一致意见。谢谢,非常感谢。 – samosaris

+0

哦,这是一个关于意外状态变化的真正好处。我一直在思考专用单用途功能,但是好的代码可以在多个地方重复使用,并且一定会出现(一个私人成员可能因为不同的原因在两个不同的地方轻松使用)。 – samosaris

+0

现在我回想起来,我认为我一直在使用示例1的主要原因是b/c说你喜欢5+数据成员,所有私有数据成员都需要设置一些数据。它真正简单,只需编写一个无效的SetData()函数而不是SetData(ref List a1,ref List a2,...) – samosaris

0

为什么不嵌入getLength()功能内容到构造,并同时做复制?你会为自己节省另一个循环。 除此之外,我很确定这并不重要。只要顺着流程走,从一个方法开始,然后在将来如果你觉得合适,就修改。

+0

这不是真正的代码,而是一个例子来说明我的问题的要点。 – samosaris

+1

在使用大型系统时,您需要考虑未来的变化。您必须做出设计决定,以便稍后在系统中简化更改。今天它正在写一种方法,然后它变成一个类,然后它变成一个包。一旦变得足够大,改变基本课程中的东西就会破坏其他许多课程,这使得返回和重构成为一种痛苦。 – Raufio

1

我会说第二个更合适,但第一个作品。

通常getter是公共的,在一个类的任何地方你可以访问一个私有变量,在同一个类中获得一个私有或受保护的变量的getter没有任何意义。如果它受到保护,您可以将功能传递给班级的子类。

这取决于你想对变量做什么。如果该值不会改变,我只需将private calculateLength()方法移到构造函数中。如果你必须重新计算它,那么我想我可以看到无效或私人在做几乎相同的事情。我觉得第二个更清晰,因为你确切知道calculateLength()方法正在返回的位置,但是在第一个方法中,它根本不知道它是否在做任何事情。做第二件事更好。

+0

...我的不好,我改变了getLength()计算长度(),因为它不是一个吸气剂,而是一个内部实用方法。绝对误导,谢谢指出。 – samosaris