方法签名最佳实践 - 重载与长名称
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了方法签名最佳实践 - 重载与长名称相关的知识,希望对你有一定的参考价值。
只是想知道你对这两种不同的方法有什么想法:重载方法与长/详细方法名称。
更新:我正在寻找一般模式/最佳实践。以下只是一个例子。
给定具有父/子关系的组织结构
> OrgUnit
> - OrgUnit
> -- OrgUnit
> -- OrgUnit
两个方法,它们在很大的部分中使用相同的代码来获取xml元素的子元素。
// 1) only 1 level down children
getSubOrgUnits()
// 2) all levels down
getSubOrgUnits(boolean includeChildren)
// 3) alternative naming of 1)
getDirectSubOrgUnits()
// 4) alternative naming of 2)
getAllSubOrgUnits()
所以1和2使用参数而3和4使用无参数命名。
你会去找什么?为什么?还要考虑1)和2)可以获得额外的参数,这些参数会产生像getChilds(true,false,null)这样的东西,但3)和4)可能会得到像getDirectSubUnitsExcludeSome()这样的名字
可以是JAVA特定的,但对此有更广泛的看法。
在我看来,使用详细的方法名称是一个更好的解决方案。
- 这更容易理解,您的代码将需要更少的评论
- 它更易于维护,您可以在不影响现有签名的情况下更改实施。您仍然可以添加新签名,而无需回归。
但要小心,在某些情况下,最好添加一些参数
例1
private List<Element> getElementsByType(MyTypeEnum type);
public List<Element> getElementsOfType1();
public List<Element> getElementsOfType2();
public List<Element> getElementsOfType3();
/* VS */
public List<Element> getElementsByType(MyTypeEnum type);
两种实现都很好,它取决于你,MyTypeEnum
的大小,它的大小增加的能力。你想揭露什么?你想让getElements***
的来电者能够获得所有类型的Element
吗?
例2
public void log(Level l, String s, Exception e);
/* VS */
public void logInfo(String s);
public void logWarning(String s);
public void logError(String s, Exception e);
在这种情况下,第二部分更好。因为它更易读,易于理解。因为当你登录INFO
和WARNING
级别时,你不需要指定Exception
。所以专业化这个方法是件好事。但是,将方法public void log(Level l, String s, Exception e);
保持公开而非私有是很重要的,因为在某些情况下使用这种通用方法会很有用。
结论
这实际上取决于具体情况,但如果您有可能添加特定方法,并使用详细的名称(专门针对目标行为),请执行此操作。
这一切都归结为味道。
作为一般惯例,您可以使用“最少的参数越好”。它在代码清晰度方面既方便又实际上节省了堆栈内存(不多,但从长远来看,每一点都很重要)。
拥有不同的名称有助于分配自动完成。
例如我会去
GetAllSubOrgUnitsList()
GetFirstSubOrgUnitsList()
之所以这样,在得到之后,我写的第一个字母将标明我想要的东西。
如您所述,如果您没有直观的名称,则可以添加默认参数。
在你的例子中,
GetDirectSubUnitsExcludingSome()
我会用一组最小的参数替换它
GetFilteredSuborgUnits(ISuborgFilter aFilter);
然后,从架构中,要求开发人员实现他们的自定义过滤器。过滤器可以要求分层深度,某些所有权等(您决定是建筑师)。
所以,作为快速总结:亲吻!
即使GetAllSuborgUnits()将提供相同的GetFilteredSubOrgUnits(null),给出一个快速而明确的行为替代方案比使用复杂的名称/参数集更好。毕竟,裁员并不总是坏事:)。
我不同意更长的名字是更好的方法。
它确实“依赖”,但让我们澄清一些事情:
- 两个方法做同样的事情,但采取不同的选择应该,恕我直言,具有相同的名称(被重载)。
- 执行不同操作的两种方法(除了由参数确定的方法之外)应该具有不同的名称。换句话说,一般函数应该有一个名称(尽管有变体),不同函数应该有不同的名称。
值得注意的是,重载是JRE中使用的几乎统一的做法。
在实际使用中,我发现较长的名字没有什么优势。诚然:
getSubOrgUnits()
比以下更明显:
getSubOrgUnits(true)
如果我将其包含在正式的API中,我会给它们单独的名称,或者将第二个作为常量:
getSubOrgUnits(INCLUDE_SUB_UNITS)
虽然大多数IDE允许您立即查看如何通过将鼠标悬停在方法上来解释true
参数(通常会在弹出窗口中显示Javadoc)。
对我来说,重载的优点在于它使变体形式正式关联。它也是Javadocs中更好的表现形式。
处理这种结构的通常方法是:
// Used when you KNOW there is only one child.
getFirstChild();
// Used when there may be many children.
getChildren();
这是XOM
getChildElements和getFirstChildElement用于遍历XML文件结构的模式。
你可以随时使用:
thing.getFirtsChild().getChildren();
进入更深层次。
首先,我称之为getChildren()
,而不是getChilds()
。 :)
如果你有几个级别,为什么不引入深度级别的参数?
// Get children up to depthLevel
getChildren(final int depthLevel)
// For convenience
getChildren()
在无参数方法的情况下,添加有意义的信息,以便其他开发人员知道您是返回全部还是仅返回第一级。
编辑:OP问:“所以一般来说你使用什么方法,为什么,哪些用例?你可以分享一下你的想法。”
这是非常基于意见的。正如@OldCurmudgeon所说,许多处理树状结构的库使用专用方法来访问下层。这很好,只要你经常这样做。另一方面,如果您想要访问特定级别的结构,引入depthLevel
参数可以为您提供更多功能。这在很大程度上取决于您的常用用例。
因此,如果您很可能需要经常获得对象的第一个孩子,请引入getFirstChild()
和getChildren()
。如果您更有可能更频繁地访问更深层次的数据,或者需要访问专用级别,请引入深度参数。
以上是关于方法签名最佳实践 - 重载与长名称的主要内容,如果未能解决你的问题,请参考以下文章