将getter和setter明确命名为“get ...”和“set ...”有什么好处?

时间:2009-08-05 01:42:21

标签: language-agnostic programming-languages accessor

这会让其他人感到沮丧吗?我更愿意看到:

 block.key(newKey);  // set the key for this block

 testKey = block.key();  // look up the key for this block

大于

 block.setKey(newKey); // set the key for this block
 testKey = block.getKey(); // look up the key for this block

首先,“set”和“get”是多余的(因此增加噪声会降低可读性)。动作(set / get)由每个语句的语法定义。我理解超载。事实上,使用相同的确切标识符强化了这些属性与对象相同。当我读“getKey()”和“setKey()”时,我可能不太确定。

其次,如果要将“get”和“set”严格解释为setter和getter,那么如果与设置/获取值相关联的其他语义(例如副作用)将会令人惊讶。

我认为这种偏见来自我的Smalltalk背景,但是在一个多态性工作得很好的世界里,如果没有“get”和“set”到处散落,我们会不会更好?如果我们不必一遍又一遍地输入这三个字母,只要想想我们可以输入多少代码?! (有点脸颊)

那里的任何人都有同样的感受吗?

11 个答案:

答案 0 :(得分:4)

C#的设计者显然同意,并且'C#'标签在StackOverflow上以2:1的比例超过了下一个最流行的语言。所以我怀疑你是在向合唱团讲道。

答案 1 :(得分:4)

有几种语言有不同的处理getter和setter的方法。在Java中,你有getName和setName,在Qt中你有name和setName。出于以下原因,我更喜欢Java方式:

  1. 如果你有一个叫做驱动器的功能怎么办?它会导致你的班级开车,还是设置/获得一个驱动器?
  2. 启用建议后,您可以输入get,然后获取所有getter。如果您不记得所需的吸气剂名称,这非常有用。
  3. 在理由一的基础上,它将功能分成不同的组。你有做某事的功能,他们不是以get或set开头的(虽然他们应该从do开始?)。然后你有获得属性的函数,它们都以get开头。然后你有了设置属性的函数,它们都以set开头。

答案 2 :(得分:3)

对我来说,getset前缀会让我的大脑在阅读代码时减少工作量。如果使用一致,get / set方法可以更轻松地对标题进行grep,可能会让课程更容易学习。使用。我花了不成比例的时间阅读代码而不是编写代码,因此getset的额外字符对我来说很好。

答案 3 :(得分:3)

Java语言目前没有属性,因此getter / setter语法已成为事实上的标准。如果您编写Java代码,那么您将很好地使用Java约定。这不仅仅是因为其他程序员可以读取您的代码,但更重要的是,构建了数百个其他Java框架来处理支持Java Bean样式getter / setter的对象。

例如,在Velocity templating engine中,您可以编写如下内容:

The answer is $block.key

以上将尝试调用:

block.getkey();
block.getKey();

如果你已经定义了block.getKey(),那么一切都会正常工作。一般来说,最好遵循语言的惯例。

答案 4 :(得分:2)

使用“get”添加访问器和使用“set”添加mutator是一种因语言而异的实践,并且似乎在Java中最常见。例如:

  • 在Python中,您具有属性的概念,因此访问器可能看起来像obj.foo,并且mutator可能看起来像obj.foo = bar(即使方法在后台调用)。类似的概念存在于Ruby等语言中。因此,在许多语言中,对访问器和变换器的调用看起来像是对实例变量的直接“调用”,并且您从未看到类似“setFoo”或“getFoo”的内容。
  • Objective-C等语言不鼓励使用“get”为访问者添加前缀,因此在Objective-C中,您会看到[obj foo][obj setFoo:bar]之类的调用。

我从来都不喜欢在Java中使用“get”前缀访问器的做法,但我确实看到使用“set”为mutator添加前缀的优点。也就是说,由于流行的做法是在Java中用“get”/“set”作为前缀,我在自己的代码中继续这种趋势。

答案 5 :(得分:2)

在C ++中我只是使用重载

int parameter() const { return m_param }
void parameter(int param) { m_param = param; }

答案 6 :(得分:2)

一般来说,属性名称应该是名词,而方法名称应该是动词,因此上面示例中的属性将被称为“驱动程序”,方法将是“驱动器”。当然会出现重叠的情况,但总的来说这有效并使代码更具可读性。

答案 7 :(得分:1)

是的,java中的get / set实际上是一种解决方法,是语言中的一个问题。

将其与c#properites进行比较

http://www.csharp-station.com/Tutorials/Lesson10.aspx

或者python http://blog.fedecarg.com/2008/08/17/no-need-for-setget-methods-in-python/

我认为这是java最大的失败之一。

答案 8 :(得分:0)

C#getter和setter是“第一类”实体,并不像语法上的函数调用那样(尽管任何代码都可以在访问器的上下文中运行)。

我只使用强制我的语言中的get / set,就像Objective-C一样。

答案 9 :(得分:0)

您可以轻松搜索代码库,以获取对getDrive()setDrive()的引用。如果您的方法名为'drive',搜索时会出现更多误报。

答案 10 :(得分:0)

听,听。

我非常喜欢getter和setter的特殊符号。 CLU做得最好:

  • 在表达式中使用p.x等同于调用get_x(p)

  • 使用p.x := e(分配)等同于致电set_x(p, e)

如果对象p的界面未导出get_xset_x,则无法执行相应的操作。简单。

让我们听听它的语法糖!