Java 方法命名约定:getter 过多

发布于 2024-09-08 22:54:55 字数 1339 浏览 4 评论 0原文

为什么 Java 方法名称如此广泛地使用“get”前缀?至少在我的Java程序中,有很多名称以“get”开头的方法。 get 方法的百分比高得令人怀疑。我开始觉得“得到”这个词由于通货膨胀而失去了意义。这是我的代码中的噪音。

我注意到函数式/声明式编程和 PL/SQL 中使用了不同的命名约定。方法名称只是说明该方法返回的内容。他们将使用 account.amount()Time,而不是 account.getAmount()Time.getIsoFormattedDateString(Date date)。 isoFormattedDateString(日期日期)。这对我来说非常有意义,因为函数的名称描述了评估该方法的结果(假设没有副作用,无论如何都不应该有副作用)。 “get”前缀似乎是多余的。

我刚刚开始阅读《清洁代码》这本书。它表示方法应该只做一件事,并且该事情通常应该是以下之一:

  1. 通知某个对象有关事件的信息,通常将事件作为参数传递。
  2. 询问有关某个对象的问题,通常使用形成自然语言语句的方法名称,将对象作为参数传递并返回布尔值。
  3. 获取某些内容,可能会传递一些查找键或一些要转换的对象作为参数,并始终返回所需的对象/值。

我的问题是关于第三类的。对于这种方法,除了“get”之外还有其他命名约定吗?选择方法名称/前缀时使用什么标准?

这是一个示例:

我有一个包含两个方法 getDates()getSpecialDates() 的类。 getDates() 只是返回私有变量的值(对日期集合的引用)。据我了解,这是一个标准的吸气剂。 getSpecialDates() 是不同的;它调用 getDates(),从另一个类获取过滤器,应用该过滤器并返回实际上是 getDates() 的子集。

getSpecialDates() 方法可以命名为 computeSpecialDates()findSpecialDates()selectSpecialDates()elicitSpecialDates() > 或其他什么。或者我可以简单地将其命名为 specialDates()。然后,为了保持一致性,我可以将 getDates() 重命名为 dates()

为什么要费力区分应该以“get”为前缀的方法和不应该以“get”为前缀的方法,以及为什么要费力寻找“get”的替换词呢?

Why do Java method names use the "get" prefix so extensively? At least in my Java programs there are a lot of methods with names starting with the word "get". The percentage of get-methods is suspiciously high. I am starting to feel that the word "get" is losing its meaning because of inflation. It is noise in my code.

I have noticed that there is a different naming convention being used in functional/declarative programming and PL/SQL. The method name simply states what the method returns. Instead of account.getAmount() or Time.getIsoFormattedDateString(Date date) they will use account.amount() and Time.isoFormattedDateString(Date date). This makes perfect sense to me, as the name of the function describes the result of evaluating the method (assuming there are no side effects, which there shouldn't be anyway). The "get" prefix seems superfluous.

I have just started reading the book "Clean Code". It says that methods should do only one thing, and that that thing should normally be one of the following:

  1. Notify some object about an event, typically passing the event as a parameter.
  2. Ask a question about some object, typically with the method name forming a natural language statement, passing the object as parameter and returning a boolean.
  3. Fetch something, possibly passing some lookup key or some object to be converted as parameter and always returning the desired object/value.

My question is about the third category. Are there naming conventions other than "get" for this kind of methods? What criteria do you use when choosing method names/prefixes?

Here is an example:

I have a class with two methods getDates() and getSpecialDates(). getDates() simply returns the value of a private variable (the reference to a collection of dates). This is a standard getter, as I understand it. getSpecialDates() is different; it calls getDates(), fetches a filter from another class, applies the filter and returns what is effectively a subset of getDates().

The method getSpecialDates() could be named computeSpecialDates(), findSpecialDates(), selectSpecialDates() or elicitSpecialDates() or whatever. Or I could simply name it specialDates(). And then, for consistency, I could rename getDates() into dates().

Why bother separating between methods that should be prefixed with "get" and methods that should not, and why bother finding replacement words for "get"?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(20

冷了相思 2024-09-15 22:54:55

我个人只要有可能就不使用 getter 和 setter(意思是:我不使用任何需要它的框架,例如 Struts)。

如果可能的话,我更喜欢编写不可变对象(公共最终字段),否则我只使用公共字段:更少的样板代码,更高的生产力,更少的副作用。 get/set 的最初理由是封装(让你的对象尽可能害羞),但事实上,我并不经常需要它。

Joshua Bloch 在 Effective Java 中提出了这一令人信服的建议:

类应该是不可变的,除非
有一个很好的理由
它们是可变的......如果一个类不能
使其不可变,限制其可变性
尽可能多。

在同一本书中,他还说(但我不想在这里复制整本书):

JavaBeans 模式有严重的
缺点。

我完全同意这一点,因为 JavaBeans 最初是为了解决一个非常狭窄的问题领域:在 IDE 中操作图形组件。使用一种解决方案来解决另一个问题是一种不好的做法。

I personally don't use getters and setters whenever it's possible (meaning : I don't use any framework who needs it, like Struts for instance).

I prefer writing immutable objects (public final fields) when possible, otherwise I just use public fields : less boiler plate code, more productivity, less side effects. The original justification for get/set is encapsulation (make your objects as shy as possible), but in fact, I don't need it very often.

In Effective Java, Joshua Bloch makes this compelling recommendation :

Classes should be immutable unless
there's a very good reason to make
them mutable... If a class cannot be
made immutable, limit its mutability
as much as possible.

In the same book, he also says (but I don't want to copy the whole book here) :

The JavaBeans pattern has serious
disadvantages.

I totally aggre with that, since JavaBeans were originally intended for a very narrow problem domain : manipulation of graphical components in an IDE. It is a bad practice to use one solution designed for solving another problem.

柠檬心 2024-09-15 22:54:55

存在如此多 get* 方法的部分原因是 Java 不支持 .net/COM 中的“属性”,并且 Java bean 和此类使用函数 getX 和 setX 来复制名为 X 的属性的功能。 Java 利用这一点来允许设置和检索属性。

Part of the reason there's so many get* methods is that Java doesn't support "properties" a la .net/COM, and Java beans and such use functions getX and setX to replicate the functionality of a property called X. Some IDEs for Java take advantage of this to allow the setting and retrieval of properties.

鹿! 2024-09-15 22:54:55

getter 和 setter 方法通常用 Java 编写的原因之一是使用 JavaBean惯例。

然而,标准 Java API 本身在这方面并不一致。例如,类 String 有一个 length() 方法,而接口 Collection 定义了一个 size() 方法,而不是getLength()getSize()

Java不支持统一访问原则,因此必须编写getter和setter方法来访问特性。

One of the reasons that getter and setter methods are often written in Java is because of the use of JavaBeans conventions.

The standard Java API isn't consistent itself with regard to this, however. For example, class String has a length() method and interface Collection defines a size() method, instead of getLength() or getSize().

Java doesn't support the uniform access principle, so you have to write getter and setter methods to access properties.

很酷不放纵 2024-09-15 22:54:55

方法名称,例如 getSpecialDates()computeSpecialDates()findSpecialDates()selectSpecialDates()elicitSpecialDates(),对我来说是命令,因为它们的名称中使用了动词(动作)。每次调用命令时都会产生副作用。而像 date()dates()specialDates() [名词] 这样的方法名称是返回有用值且没有副作用的方法。多次调用该方法每次都会返回相同的值,除非调用的命令的副作用是更改状态。

Method names like getSpecialDates(), computeSpecialDates(), findSpecialDates(), selectSpecialDates() and elicitSpecialDates(), to me are commands because of the use of verbs (actions) in their names. Commands are meant to have side effects everytime you call them. Whereas method names like date(), dates(), specialDates() [nouns] are methods that return a useful value with no side effects. Calling the method multiple times returns the same value everytime, unless a command is called whose side effect is to change state.

痴情 2024-09-15 22:54:55

原因之一是它是 Java Bean 规范的重要组成部分

One reason is that it is an essential part of the Java Bean Spec.

说谎友 2024-09-15 22:54:55

要求 Java 开发人员使用通用 get/set 约定的原因之一是许多框架依赖它来创建 bean 和设置字段。例如,如果您为 Spring bean 配置了一些属性,如 并且没有名为 setFoo() 的方法> 在课堂上,您将在创建 bean 时遇到错误。

One of reasons that require Java developers to use common get/set convention is that many frameworks rely on it for bean creation and setting the fields. For example, if you have some property configured for Spring bean like <property name="foo" value="bar" /> and there's no method named setFoo() in the class, you'll get an error on bean creation.

猥︴琐丶欲为 2024-09-15 22:54:55

前提 1:一个方法应该只做一件事。前提 2:一个 getter 方法——无论它是否使用 get 前缀——应该没有副作用。考虑到这两个前提,我建议:一种以相对简单且廉价的方式获取某些内容的方法,其名称中不需要有动词。

getter 存在的理由不是做某事,而是评估某事。我们对该方法的作用不感兴趣。。由于它没有副作用,因此该方法中进行的任何计算都没有任何意义。我们只对方法返回的内容感兴趣。方法名称应该以名词的形式反映这一点。仅由名词组成的方法名称应始终为“getters”。

前缀“get”中的信息可以通过缺少动词来推断。这比使用 get 前缀更简单、更直观。

名称仅由名词组成并具有返回值的方法可以被认为没有副作用并且相对便宜。名称包含动词且没有返回值的方法存在副作用。名称包含动词并具有返回值的方法可以被认为是相对昂贵的并且可能有副作用。

似乎每个人都在各处写“get”的原因仅仅是源自 JavaBeans 模式的教条传统。当您真正计划使用需要它的工具/框架时,请保留 get 前缀!

Premise 1: A method should do only one thing. Premise 2: A getter method - wether it uses the get prefix or not - should have no side effects. Given these two premises I propose: A method whose role is to fetch something and that does so in a relatively simple an inexpensive manner need not have a verb in its's name.

The raison d'etre of a getter is not do something but to evaluate to something. We are not interested in what the method does. Since it has no side effects, whatever computation goes on in the method cannot be of any interest. We are only interested in what the method returns. The method name should reflect that in the form of a noun. Method names consisting only of nouns should always be "getters".

The information in the prefix "get" can be inferred from the lack of verbs. This is simpler and more intuitive than using the get prefix.

A method whose name consists of only a noun and has a return value can be assumed to have no side effects and to be relatively cheap. A method whose name contains a verb and does not have a return value exists to have side effects. A method whose name contains a verb and has a return value can be assumed to be relatively expensive and may have side effects.

It seems the reason everybody is writing "get" all over the place is merely dogmatic tradition originating from the JavaBeans pattern. Leave the get prefix for when you actually plan to use tools/frameworks that need it!

分开我的手 2024-09-15 22:54:55

就我个人而言,我沉迷于 get。这只是人类的语言。当你想要某样东西时,你就想得到某样东西。 get 前缀没有任何问题。关于命名约定,我可以想到数据库查询的 Select 前缀 - 例如 SelectUsers

Personally, I am addicted to get. It is just the human language. When you want something, you want to get something. There is nothing wrong with get prefixes. About the naming convention, I can think of the Select prefix for database queries - SelectUsers for example.

ゞ花落谁相伴 2024-09-15 22:54:55

正如许多人已经指出的那样,get..() 和 set()... 是 Java Beans 约定的一部分。这对于与 Java 规范的其他部分进行互操作是必要的。例如,在 JSP 中,您可以通过指定不带 get 前缀的属性名称来访问 Java 中的成员。

给定 bean:-

public class Foo {
  public int getX() { return 1; }
}

我们可以执行以下 JSP 来获取 X:-

<jsp:useBean id="aFoo" class="Foo" />
<c:out value="${aFoo.X}" />

这种方法除了“get”之外还有其他命名约定吗?

是的,您可以使用 is 而不是 get 来获取布尔属性。

As many people have already stated, get..() and set()... are part of the Java Beans Convention. This is necessary for interoperation with other parts of the Java Spec. For example, in JSP you can access members from a Java been by specifying the property name without the get prefix.

Given the bean:-

public class Foo {
  public int getX() { return 1; }
}

We can do the following JSP to get X: -

<jsp:useBean id="aFoo" class="Foo" />
<c:out value="${aFoo.X}" />

Are there naming conventions other than "get" for this kind of methods?

Yes you can use is instead of get for boolean properties.

弱骨蛰伏 2024-09-15 22:54:55

当我们生活在这样一个时代,任何值得拥有的 IDE 都会为你的私有变量生成 getter 和 setter,并且如果你不想阅读它们,你可以将它们折叠起来,那么“get”有什么关系呢?

你真正的问题应该是关于设计:为什么你的对象有这么多属性?如果你的对象只有 getter 和 setter,那么你是否患有“贫血领域模型”?

C# {get, set} 表示法稍微好一些,因为它减少了代码行数,但您仍然需要为每个变量键入令人讨厌的“get”。

What does "get" matter when we live in a day and age where any IDE that's worth having will generate getters and setters for your private variables and lets you fold them up if you'd rather not read them?

Your real issue should be about design: Why do your objects have so many attributes? If your objects have nothing but getters and setters, are you suffering from an "anemic domain model"?

The C# {get, set} notation is marginally better, because it cuts down on the lines of code, but you still have that pesky "get" to type for every variable.

请爱~陌生人 2024-09-15 22:54:55

正如其他人提到的,它是针对 Java Beans 的。但是,如果您使用 Java,请只命名方法 getXXX()(如果它仅返回一个值且不执行任何其他操作)。就像您暗示的那样,如果它正在执行其他操作,请将其命名为不同的名称,例如computeXXX()。

我有时会发现 getXXX() 方法有 50 行代码 - 如果是这种情况,那么你就做错了。

As others have mentioned, it is for Java Beans. However, if you are using Java, PLEASE only name a method getXXX() if it only returns a value and does nothing else. Like you hinted at, if it is doing something else, name it something different such as computeXXX().

I sometimes find getXXX() methods with 50 lines of code - if this is the case, you are doing it wrong.

演多会厌 2024-09-15 22:54:55

我开始觉得这个词
“得到”正在失去意义,因为
通货膨胀。这是我的代码中的噪音。

我稍微不同意这个结论。我不会说它失去了意义,我想说的是,由于它被广泛使用,带有 get 前缀的方法几乎可以完成您期望它们做的事情。

对于以下示例:

Time.isoFormattedDateString(Date date)

这是否根据输入参数设置格式类型,以便所有后续调用都将使用此格式?

我知道有人得出这个结论有点牵强,因为它是一个静态方法,但是您能确定这个方法是否是在实例上调用的吗?可能吧,但是 get 的使用消除了所有歧义:

getIsoFormattedDateString(Date date)

在我看来,属性是比完全放弃 get 更优雅的解决方案。

I am starting to feel that the word
"get" is losing its meaning because
of inflation. It is noise in my code.

I would slightly disagree with this conclusion. I wouldn't say it loses its meaning, I would say that as it is widely used that methods with the get prefix will do pretty much what you expect them to do.

For the following example:

Time.isoFormattedDateString(Date date)

Does this set the format type based on the input parameter so all subsequent calls will use this format?

I know it is a bit of a stretch that someone would come to that conclusion as it is a static method but would you be as sure if this method was called on an instance? Probably, but the use of get removes all ambiguity:

getIsoFormattedDateString(Date date)

In my opinion, properties are a more elegant solution than dropping get altogether.

青衫儰鉨ミ守葔 2024-09-15 22:54:55

历史片段:如果您查看一些最早的 Java 1.0 API(JavaBeans 之前),您会发现它们没有“get”前缀。例如,java.awt.Container#minimumSize() 已被弃用,取而代之的是#getMinimumSize()。

Historical snippet: If you look at some of the very earliest Java 1.0 APIs (pre JavaBeans), you'll see they don't have the 'get' prefix. For example java.awt.Container#minimumSize() was deprecated in replace by #getMinimumSize().

柠檬色的秋千 2024-09-15 22:54:55

我认为这是“给你的变量和函数赋予有意义的名称”理想的一个子集。

正如许多人所指出的,“get”在 Java Bean 中具有特定的含义。因此,我认为它应该仅限于用于检索内部变量的值,可能会产生副作用。我认为如果“获取”涉及少量计算,例如进行数据类型转换或从嵌入类中提取值或重新解释其他值,例如“public int getRightMargin() { return width-margin.left; }”,那么这是可以接受的。任何副作用都应仅限于获取该值时真正的“副作用”,例如设置一个表示已检索到该值的标志。

但如果有严肃的计算,我认为它不应该被称为“get”。也许是“计算”或其他什么。

如果我们在命名函数时使用一致的术语,那就太好了,就像我们都同意“读取”意味着主要活动是从数据库中检索某些内容,而“计算”意味着进行计算或类似操作一样。但这可能是不现实的:也许有太多存在细微差别的案例。

I think this is a subset of the "give your variables and functions meaningful names" ideal.

"get" has a specific meaning in Java Beans as many have noted. I think it should therefore be limited to being used to retrieve the value of an internal variable, possibly with side effects. I think it's acceptable if "getting" involves minor computation, like doing a data type conversion or extracting a value from an embedded class or reinterprerting other values, like "public int getRightMargin() { return width-margin.left; }". Any side effects should be limited to things that are truly "side effects" of getting the value, like setting a flag that says it has been retrieved.

But if there's serious computation, I don't think it should be called "get". Maybe "calc" or whatever.

It would be good if we had consistent terms to use in naming functions, like if we all agreed that "read" means that the main activity is to retrieve something from a database while "calc" meant to do calculations or some such. But that might be unrealistic: maybe there are too many cases with subtle differences.

感情旳空白 2024-09-15 22:54:55

一种选择是保留返回原始值或不可变值的方法的 get 前缀,但删除返回可用于修改原始接收者的引用的方法的前缀。

例如,在 java.util.Map 中,size() 可以调用 getSize()keySet()被称为getKeySet()

One option is to keep the get prefix for methods that return primitive or immutable values, but drop the prefix for methods that return references that can be used to modify the original recipient.

e.g. in java.util.Map, size() could be called getSize() but keySet() would not be called getKeySet().

潦草背影 2024-09-15 22:54:55

我仅将 get 和 set 用于仅获取或设置属性而不是其他属性的方法。

I use get and set only for methodes that only get or set a property and not mutch else.

空宴 2024-09-15 22:54:55

Java Bean 对其命名约定非常严格,例如
假设你声明一个变量名Name,对应的setter为setName()。但它会产生错误,因为 setName 必须对应于“name”而不是 Name。
另一个布尔值的例子是Readey;与 getter isReady() 一起使用。当它寻找布尔准备就绪时再次出错。
因此,在编写代码之前,您必须熟悉此命名约定。
但我个人更喜欢这种约定,因为它使程序员的工作变得容易,并且在您使用它几分钟后似乎有点合乎逻辑。

Java Beans get very sticky to its naming conventions, like
suppose you declare a variable name Name, with corresponding setter as setName(). But it would generate an error as, setName must correspond to 'name' instead of Name.
Another example boolean isReadey; with getter isReady(). Again error as it look for boolean ready.
So, prior to code you must be familiar with this naming convention.
But i personally prefer this convention as it makes programmer's work easy and seems to be a bit logical after few moments u spend with it.

贱贱哒 2024-09-15 22:54:55

好吧,虽然 JavaBeans 规范要求您声明 getter 和 setter,但我通常不会声明它们,除非绝对必要(就像许多 MVC 框架的情况一样)。我在 Java 职业生涯中经历了很多摇摆,我倾向于将变量声明为公共(是的,这听起来有点非 OOPy)。但我喜欢它,因为它看起来很简洁,而且“我”知道我在做什么。它唯一的优点是减少了行数。

Well, although JavaBeans spec asks you to declare getters and setters, I usually will not declare them unless it's absolutely necessary (as in case of many MVC frameworks). I did a lot of swing in my Java career and I tend to declare variables as public (yeah it sounds a bit non OOPy). But I liked it since it looked concise and 'I' know what I'm doing. The only advantage that it had is the reduced number of lines.

多彩岁月 2024-09-15 22:54:55

保留“get”前缀很重要,因为:

  • 方法应该声明一个操作,因此它的名称中必须包含动词

  • get 显示变量的状态不会改变

  • 区分方法 account() 来自此表达式中的变量 account

    newAccount = currentAccount + account() --- 这个 account() 做什么?


您在代码中看到太多 getter 的原因应该让您担心!

  • 要么将您的类分成较小的类,要么
  • 更好地隐藏您的代码,因为您不必透露您的类实习生,甚至应该尽量隐藏它们!

It's important that the "get" prefix remains because:

  • a method should state an action, therefore it must contain a verb in its name

  • get shows that the state of a variable won't change

  • how easy would you distinguish the method account() from the variable account in this expression :

    newAccount = currentAccount + account() --- what does this account() do ?


The reason you see too much getters in your code should worry you!

  • Either you separate your classes to smaller ones or
  • just hide your code better, because you don't have to reveal your classes interns and even should try to hide them as much as you can!
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文