如何以及为什么在带有“ get”和“ find”前缀的命名方法之间做出决定


47

我总是很难确定是否应该以getSomethingvs 开头的某个方法findSomething

问题在于为设计不当的API 创建帮助程序。当从对象获取数据时通常会发生这种情况,这需要对象作为参数。这是一个简单的示例:

public String getRevision(Item item) {
    service.load(item, "revision");
    // there is usually more work to do before getting the data..
    try {
        return item.get_revision();
    }
    catch(NotLoadedException exception) {
        log.error("Property named 'property_name' was not loaded", exception);
    }
    return null;
}

如何以及为什么要在将此方法命名为getRevision()or时做出决定findRevision()


2
设计较差的API 的最佳帮手不是搞砸棘手的命名,而是建立一个反腐败层:“如果您的应用程序需要处理其模型不适合或不适用于您自己的应用程序中的模型的数据库或其他应用程序,使用AnticorruptionLayer与该模型以及您的模型进行转换。”
蚊蚋

1
我以前从未听说过这个概念。您是否与示例有更好的链接?
knownasilya

1
搜索网络,上面有很多信息。例如,反腐败层剖析,第1部分 “很可能……您不可避免地面临着与已经存在的意大利面条进行交互的任务。进入反腐败层……”
gnat

Answers:


82

Get当我知道检索时间将非常短时(例如在从哈希表或btree进行查找时),我就使用该方法。

Find暗示需要“更长”的时间来执行(对于更长的某个任意值)的搜索过程或计算算法。


3
+1我在检索时使用get并查找何时需要完成工作才能进行get。
2013年

5
考虑到代码会发生变化(某些部分已优化,算法也会发生变化),并且更改API常常是不可能的,因为它看起来并不正确。如果以后替换find为哈希表算法,该怎么办?
梅兹

2
我还要假设,在阅读呼叫时,由于搜索条件不成功而查找失败时,可能会调用“查找”,而除非有一些异常问题,否则“获取”有望成功。
gnasher729

如果函数接受可选参数以根据某些条件过滤结果怎么办?双方getfind就取决于如何使用它适用。
ESR

61

我会说这find可能会失败,但get不应该。


25
如果您的意思是find可以返回NULL而get不会返回NULL但可能抛出(或断言),我同意。
Sjoerd 2013年

1
我对此完全同意@Sjoerd。
mhr 2013年

那如果find()回报Optional<>呢?在那种情况下find也是null安全的。
TheCoder

42

引用我经常与我的孩子进行的对话:

我: 嘿,小子!去找我一些电池

小子:但是他们在哪里?

我:那就是为什么我告诉你去找他们。如果我知道他们在哪里,我会告诉你去拿他们。或者你可以问你的母亲。

同样的想法成立:

  • 对于返回廉价信息(并且可以内联或以其他方式进行优化)的方法使用“ get”,或对该对象唯一拥有的信息使用“ get”。

  • 使用“查找”作为一种确实可以获取一条信息或使用其他对象进行查找的方法。


16
只有程序员才会与他们的孩子进行这种交谈。“你想拿垃圾吗?” “没有。” “你会把垃圾拿出来吗?” “是。”
罗伯特·哈维

@RobertHarvey我想我遇到了这个问题。每当有人试图解释某事或提出一个问题时,我通常都会回问并告诉他们明确的问题。否则,我们通常会遇到XY问题。如果我不这样做,我会感觉像是步行自动完成功能。您不知道您在想什么,您无法把它写成文字,您对几个单词couple不休,并希望我为您做所有的“思考”并为您提供帮助?不,没有发生:)
akinuri

3

Find表示没有结果,例如执行带有某些参数的数据库查询时,这些参数可能在调用之间改变。另一方面,Get表示结果是方法事先已知的,或者一旦知道就不会更改,即调用没有参数。
因此,我将使用例如Customer findCustomerById(long customerId)和Customer getCustomer()


3

我采用以下模式:

  • Foo GetFoo() 不能返回null并且复杂度为O(log(n))或更小
  • bool TryGetFoo(out Foo) 可以返回null并且复杂度为O(log(n))或更小
  • Foo FindFoo() 不能返回null并且它的复杂度大于O(log(n))
  • bool TryFindFoo(out Foo) 可以返回null并且它的复杂度大于O(log(n))

这样,代码就可以清楚地表明意图和复杂性。

通常,getter用于直接列表或字典/集合访问。
查找器是深度搜索,列表的完整扫描等。

在您的情况下:

public bool TryGetRevision( Item item, out String revision ) 
{
    service.load( item, "revision" );
    // there is usually more work to do before getting the data..
    try 
    {
        revision = item.get_revision();
        return true;
    }
    catch( NotLoadedException exception )
    {
        log.error( "Property named 'property_name' was not loaded", exception );
        revision = "";
        return false;
    }
}

+1,即try简短又准确
SpaceTrucker 2013年

2

get在任何情况下都是适用的_实际上,通常会假设为了获得某些东西,您首先需要找到它。因此,如果不确定,请使用get

我将使用find诸如findMinimum()或之类的方法findOptimal(),即有一些特殊的算法来计算返回值,而不仅仅是向数据库,文件系统,远程服务器等发出请求以接收一些数据。


1
好点。我个人可能不会find在您提供的示例中将其用作前缀。对于计算任务,例如您的示例中的任务,我将使用calculatecompute
已知


1

我通常会使用它Get来检索对象/值,并Find检索其位置(例如,在数组中)。

例如:

object o = obj.GetItem( 'name');

integer i = somearray.Find( 'name');

0

对我来说,find意味着可能存在不止一个结果。 get仅暗示一个。


8
似乎有这种感觉,但我不确定我是否完全同意。想想这样说:getCatVS findCatVS getCatsVS findCats。将find..仍然是返回单一对象。我认为应将复数形式添加到名词中。
已知的原因2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.