วิธีและเหตุผลในการตัดสินใจระหว่างวิธีการตั้งชื่อด้วยคำนำหน้า "รับ" และ "ค้นหา"


47

ฉันมักจะมีปัญหาในการหาว่าผมควรจะตั้งชื่อวิธีการบางอย่างที่เริ่มต้นด้วยเมื่อเทียบกับgetSomethingfindSomething

ปัญหาอยู่ในการสร้างผู้ช่วยเหลือสำหรับ 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()หรือfindRevision()?


2
ผู้ช่วยที่ดีที่สุดสำหรับ API ที่ออกแบบมาไม่ดีจะไม่ยุ่งกับการตั้งชื่อที่ยุ่งยาก แต่สร้างAnticorruption Layer : "หากแอปพลิเคชันของคุณต้องจัดการกับฐานข้อมูลหรือแอปพลิเคชันอื่นที่มีโมเดลที่ไม่พึงประสงค์หรือไม่เหมาะสมกับโมเดล ใช้ AnticorruptionLayer เพื่อแปลเป็น / จากโมเดลและของคุณ "
ริ้น

1
ฉันไม่เคยได้ยินแนวคิดนี้มาก่อน คุณมีลิงค์ตัวอย่างที่ดีกว่านี้ไหม?
knownasilya

1
ค้นหาเว็บมีข้อมูลจำนวนมาก เช่นกายวิภาคของชั้นต่อต้านการคอร์รัปชั่นตอนที่ 1 "เป็นไปได้ว่า ... คุณต้องเผชิญกับภารกิจในการโต้ตอบกับปาเก็ตตี้ที่มีอยู่แล้วอย่างหลีกเลี่ยงไม่ได้ใส่เลเยอร์ต่อต้านการทุจริต ... "
gnat

คำตอบ:


82

ฉันใช้Getเมื่อฉันรู้ว่าเวลาการดึงข้อมูลจะสั้นมาก (เช่นในการค้นหาจากตารางแฮชหรือ btree)

Findแสดงถึงกระบวนการค้นหาหรืออัลกอริธึมการคำนวณที่ต้องใช้ระยะเวลา "นาน" ในการดำเนินการ (สำหรับค่าที่กำหนดเองนานกว่านั้น)


3
+1 ฉันใช้รับเมื่อดึงและค้นหาเมื่องานต้องทำเพื่อให้ได้รับ
Jim

5
โดยคำนึงถึงการเปลี่ยนแปลงรหัส (บางส่วนได้รับการปรับให้เหมาะสมที่สุดและการเปลี่ยนแปลงอัลกอริธึม) และการเปลี่ยน API มักจะเป็นไปไม่ได้ที่จะไม่ดูเหมือนเกณฑ์ที่ถูกต้อง คุณจะทำอย่างไรถ้าคุณแทนที่findด้วยอัลกอริทึมแฮชตารางในภายหลัง
meze

2
ฉันจะสมมติว่าเมื่ออ่านการเรียกว่า "ค้นหา" อาจถูกเรียกเมื่อการค้นหาไม่สำเร็จเนื่องจากเกณฑ์การค้นหาไม่สำเร็จในขณะที่ "รับ" คาดว่าจะประสบความสำเร็จเว้นแต่จะมีปัญหาบางอย่างผิดปกติ
gnasher729

เกิดอะไรขึ้นถ้าฟังก์ชั่นยอมรับพารามิเตอร์ทางเลือกเพื่อกรองผลลัพธ์ตามเงื่อนไขบางอย่าง? ทั้งสองgetและfindจะนำไปใช้ขึ้นอยู่กับวิธีการใช้งาน
ESR

61

ฉันจะบอกว่าfindอาจล้มเหลว แต่getไม่ควร


25
หากคุณหมายความว่าfindสามารถคืนค่า NULL ในขณะที่getจะไม่ส่งคืน NULL แต่อาจโยน (หรือยืนยัน) ฉันเห็นด้วย
Sjoerd

1
ฉันเห็นด้วยกับ @Sjoerd โดยสมบูรณ์เกี่ยวกับเรื่องนี้
mhr

และถ้าfind()ผลตอบแทนเป็นOptional<>อย่างไร ในกรณีfindนี้ยังnullปลอดภัย
TheCoder

42

หากต้องการพูดบทสนทนาที่ฉันมักมีกับลูก ๆ ของฉัน:

ฉัน: เฮ้เด็ก! ไปหาฉันแบตเตอรี่บางส่วน

เด็ก:แต่พวกเขาอยู่ที่ไหน

ฉัน:นั่นคือเหตุผลที่ฉันบอกให้คุณไปหาพวกเขา ถ้าฉันรู้ว่าพวกเขาอยู่ที่ไหนฉันจะบอกให้คุณไปหาพวกเขา หรือคุณสามารถถามแม่ของคุณ

ความคิดเดียวกันถือ:

  • ใช้ "รับ" สำหรับวิธีการที่ส่งคืนชิ้นส่วนของข้อมูลที่มีราคาถูก (และอาจเป็นแบบอินไลน์หรือปรับให้เหมาะสมเป็นอย่างอื่น) หรือสำหรับชิ้นส่วนของข้อมูลที่เป็นเจ้าของวัตถุนี้โดยเฉพาะ

  • ใช้ "ค้นหา" สำหรับวิธีการที่ทำงานเพื่อรับข้อมูลหรือใช้วัตถุอื่นเพื่อค้นหา


16
มีเพียงโปรแกรมเมอร์เท่านั้นที่จะได้สนทนากับลูก ๆ ของพวกเขา "คุณต้องการนำถังขยะออกไปหรือไม่" "ไม่" "คุณจะนำถังขยะออกไปหรือไม่" "ใช่."
Robert Harvey

@ RobertHarvey ฉันคิดว่าฉันมีปัญหากับคนอื่น เมื่อใดก็ตามที่มีคนพยายามอธิบายบางสิ่งหรือถามคำถามฉันมักจะถามคำถามกลับมาและบอกให้พวกเขาทราบอย่างชัดเจน มิฉะนั้นเรามักจะจบลงด้วยปัญหา XY หากฉันไม่ทำเช่นนั้นฉันรู้สึกว่าเป็นคุณสมบัติการเติมข้อความอัตโนมัติขณะเดิน คุณไม่รู้ว่ามีอะไรอยู่ในใจคุณไม่สามารถพูดออกมาเป็นคำพูดพูดพล่าม ๆ และคาดหวังให้ฉันทำ "ความคิด" ทั้งหมดให้คุณและช่วยคุณได้ ไม่ไม่เกิดขึ้น :)
akinuri

3

ค้นหาบอกเป็นนัยถึงการไม่มีผลลัพธ์เช่นเมื่อดำเนินการแบบสอบถามฐานข้อมูลด้วยพารามิเตอร์บางอย่างที่อาจเปลี่ยนแปลงระหว่างการโทร รับในทางกลับกันแสดงถึงผลลัพธ์เป็นวิธีการที่รู้จักกันก่อนหรือจะไม่เปลี่ยนครั้งเดียวที่รู้จักกันว่าไม่มีพารามิเตอร์ในการโทร
ดังนั้นฉันจะใช้ตัวอย่างเช่นลูกค้า findCustomerById (ยาว customerId) และลูกค้า getCustomer ()


3

ฉันใช้รูปแบบต่อไปนี้:

  • Foo GetFoo() ไม่สามารถคืนค่าว่างได้และความซับซ้อนของมันคือ O (log (n)) หรือน้อยกว่า
  • bool TryGetFoo(out Foo) สามารถคืนค่า null และความซับซ้อนของมันคือ O (log (n)) หรือน้อยกว่า
  • Foo FindFoo() ไม่สามารถคืนค่าว่างเปล่าและความซับซ้อนมากกว่า O (บันทึก (n))
  • bool TryFindFoo(out Foo) สามารถคืนค่า null และความซับซ้อนของมันเป็นมากกว่า O (log (n))

วิธีนี้ทำให้โค้ดนั้นชัดเจนในจุดประสงค์และความซับซ้อนที่คุณคาดหวัง

โดยทั่วไปแล้ว Getters ใช้สำหรับรายการโดยตรงหรือการเข้าถึงพจนานุกรม / ชุด
Finders คือการค้นหาที่ลึกการสแกนแบบเต็มรายการ ฯลฯ

ในกรณีของคุณ:

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

2

getมีความเหมาะสมในทุกกรณี _ ในความเป็นจริงมันมักจะสันนิษฐานว่าเพื่อให้ได้สิ่งที่คุณต้องค้นหาก่อน getดังนั้นหากคุณไม่แน่ใจว่าการใช้งาน

ฉันจะใช้findสำหรับวิธีการเช่นfindMinimum()หรือfindOptimal()ที่มีอัลกอริทึมพิเศษบางอย่างที่คำนวณค่าส่งคืนและไม่เพียงแค่ขอให้ DB, ระบบไฟล์เซิร์ฟเวอร์ระยะไกล ฯลฯ เพื่อรับข้อมูลบางอย่าง


1
จุดที่ดี โดยส่วนตัวฉันอาจไม่ได้ใช้findเป็นคำนำหน้าในตัวอย่างที่คุณให้ไว้ สำหรับงานคำนวณเช่นคนในตัวอย่างของคุณผมจะใช้หรือcalculate compute
knownasilya

2

ห้ามใช้ find หรือรับส่วนนำหน้า นี่เป็นการละเมิดUniformAccessPrincipleประกาศเกียรติคุณจาก bertrand meyer ทำไมไม่สร้างวิธีการดังต่อไปนี้:

public String revision(Item item)

ฉันเห็นด้วยกับคุณดีมาก !!!!
Irakli Gabisonia

1

โดยทั่วไปฉันจะใช้Getเพื่อดึงข้อมูลวัตถุ / ค่าและFindเพื่อเรียกคืนตำแหน่ง (ตัวอย่างเช่นในอาร์เรย์)

สำหรับอดีต:

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

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

0

สำหรับฉันfindหมายความว่าอาจมีผลลัพธ์มากกว่าหนึ่งรายการ getบอกเป็นนัยเดียว


8
ดูเหมือนว่าจะมีความรู้สึกนั้น แต่ฉันไม่แน่ใจว่าฉันเห็นด้วยอย่างสมบูรณ์ คิดว่าวิธีนี้: getCatVS findCatVS VSgetCats ยังคงแสดงให้เห็นถึงวัตถุเอกพจน์ถูกส่งกลับ พหูพจน์ควรเพิ่มในคำนามในความคิดของฉัน findCatsfind..
knownasilya
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.