Bagaimana dan mengapa memutuskan antara metode penamaan dengan awalan "get" dan "find"

48

Saya selalu mengalami kesulitan mencari tahu apakah saya harus menyebutkan metode tertentu dimulai dengan getSomethingversus findSomething.

Masalahnya terletak pada pembuatan pembantu untuk API yang dirancang dengan buruk. Ini biasanya terjadi ketika mendapatkan data dari suatu objek, yang membutuhkan objek sebagai parameter. Ini adalah contoh sederhana:

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;
}

Bagaimana dan mengapa harus memutuskan antara memberi nama metode ini sebagai getRevision()atau findRevision()?

diketahuiasilya
sumber
2
penolong terbaik untuk API yang dirancang dengan buruk adalah tidak mengacaukan penamaan yang rumit tetapi membangun Layer Anti Korupsi : "Jika aplikasi Anda perlu berurusan dengan database atau aplikasi lain yang modelnya tidak diinginkan atau tidak dapat diterapkan pada model yang Anda inginkan dalam aplikasi Anda sendiri, gunakan AnticorruptionLayer untuk menerjemahkan ke / dari model itu dan milik Anda. "
nyamuk
1
Saya belum pernah mendengar konsep ini sebelumnya. Apakah Anda memiliki tautan yang lebih baik dengan contoh?
knownasilya
1
Cari di web, ada cukup banyak info di dalamnya. Misalnya, Anatomi Lapisan Anti Korupsi, Bagian 1 "kemungkinan ... Anda pasti dihadapkan dengan tugas berinteraksi dengan spageti yang sudah ada di sana. Masukkan Lapisan Anti Korupsi ..."
gnat

Jawaban:

83

Saya menggunakan Getketika saya tahu waktu pengambilan akan sangat singkat (seperti dalam pencarian dari tabel hash atau btree).

Findmenyiratkan proses pencarian atau algoritma komputasi yang membutuhkan periode waktu "lebih lama" untuk dieksekusi (untuk beberapa nilai arbitrer lebih lama).

Robert Harvey
sumber
3
+1 Saya menggunakan get ketika mengambil dan menemukan kapan pekerjaan harus dilakukan untuk mendapatkan.
Jim
5
Memperhatikan perubahan kode (beberapa bagian menjadi dioptimalkan dan algoritma berubah) dan mengubah API sering kali tidak terlihat seperti kriteria yang tepat. Apa yang akan Anda lakukan jika Anda mengganti finddengan algoritma hash-table nanti?
meze
2
Saya juga akan berasumsi, ketika membaca panggilan, bahwa "menemukan" dapat dipanggil ketika menemukan itu tidak berhasil karena kriteria pencarian tidak berhasil, sementara "mendapatkan" diharapkan berhasil kecuali ada masalah yang tidak biasa.
gnasher729
Bagaimana jika fungsi menerima parameter opsional untuk memfilter hasil berdasarkan kondisi tertentu? Keduanya getdan findakan berlaku tergantung pada bagaimana itu digunakan.
ESR
62

Saya akan mengatakan itu findmungkin gagal tetapi gettidak seharusnya.

coredump
sumber
25
Jika Anda bermaksud yang finddapat mengembalikan NULL sementara gettidak akan pernah mengembalikan NULL tetapi mungkin melempar (atau menegaskan), saya setuju.
Sjoerd
1
Saya sangat setuju dengan @Sjoerd tentang hal ini.
mr
Dan bagaimana jika find()pengembaliannya Optional<>? Dalam hal findini juga nullaman.
TheCoder
42

Mengutip percakapan yang sering saya lakukan dengan anak-anak saya:

saya: Hei nak! Pergi cari aku beberapa baterai

anak: Tapi di mana mereka?

saya: Itu sebabnya saya bilang pergi mencari mereka. Jika saya tahu di mana mereka berada, saya akan memberitahu Anda untuk mengambilnya . Atau Anda bisa bertanya pada ibumu.

Gagasan yang sama berlaku:

  • gunakan "dapatkan" untuk metode yang mengembalikan sepotong informasi yang tersedia dengan harga murah (dan mungkin dapat diuraikan atau dioptimalkan), atau untuk sepotong informasi yang dimiliki secara unik oleh objek ini.

  • gunakan "find" untuk metode yang berfungsi untuk mendapatkan informasi, atau menggunakan objek lain untuk menemukannya.

jimwise
sumber
16
Hanya seorang programmer yang akan melakukan percakapan ini dengan anak-anak mereka. "Kamu mau membuang sampah?" "Tidak." "Apakah kamu akan mengambil sampah?" "Iya."
Robert Harvey
@ RobertTarvey Saya rasa saya mengalami masalah dengan orang-orang. Setiap kali seseorang mencoba menjelaskan sesuatu, atau mengajukan pertanyaan, saya biasanya mengajukan pertanyaan kembali dan memberi tahu mereka secara eksplisit tentang hal itu. Kalau tidak, kita biasanya berakhir dengan masalah XY. Jika saya tidak melakukan itu, saya merasa seperti fitur pelengkapan otomatis berjalan. Anda tidak tahu apa yang ada dalam pikiran Anda, Anda tidak dapat memasukkannya ke dalam kata-kata, Anda mengoceh beberapa kata dan berharap saya melakukan semua "pemikiran" untuk Anda dan membantu Anda dengan itu? Tidak, tidak terjadi :)
akinuri
3

Find menyiratkan tidak memiliki hasil, seperti ketika menjalankan query database dengan beberapa parameter yang dapat berubah di antara panggilan. Dapatkan, di sisi lain, menyiratkan hasil yang diketahui metode sebelumnya atau tidak akan berubah setelah diketahui, bahwa tidak ada parameter untuk panggilan.
Jadi, saya akan menggunakan misalnya Customer findCustomerById (long customerId) dan Customer getCustomer ()

jwenting
sumber
3

Saya menerapkan pola berikut:

  • Foo GetFoo() tidak dapat mengembalikan nol dan kompleksitasnya adalah O (log (n)) atau kurang
  • bool TryGetFoo(out Foo) dapat mengembalikan nol dan kompleksitasnya adalah O (log (n)) atau kurang
  • Foo FindFoo() tidak dapat mengembalikan nol dan kompleksitasnya lebih dari O (log (n))
  • bool TryFindFoo(out Foo) dapat mengembalikan nol dan kompleksitasnya lebih dari O (log (n))

Dengan begitu kode ini cukup jelas tentang maksud dan kompleksitas yang dapat Anda harapkan.

Biasanya, Getters adalah untuk daftar langsung atau akses kamus / set.
Pencari adalah pencarian dalam, pemindaian daftar lengkap, dll ...

Dalam kasus Anda:

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;
    }
}
Cyril Gandon
sumber
+1 untuk try, pendek dan tepat
SpaceTrucker
2

getcocok dalam kasus apa pun _ pada kenyataannya sering diasumsikan bahwa untuk mendapatkan sesuatu yang Anda perlu menemukan itu terlebih dahulu. Jadi, jika Anda tidak yakin, gunakan get.

Saya akan menggunakan finduntuk metode seperti findMinimum()atau findOptimal(), yaitu di mana ada beberapa algoritma khusus yang menghitung nilai kembali, dan tidak hanya membuat permintaan ke DB, sistem file, server jauh, dll untuk menerima beberapa data.

superM
sumber
1
Poin bagus. Secara pribadi saya mungkin tidak akan menggunakan findawalan dalam contoh yang Anda berikan. Untuk tugas komputasi, seperti yang ada dalam contoh Anda, saya akan menggunakan calculateatau compute.
knownasilya
2

Jangan gunakan temukan atau dapatkan awalan. Ini adalah pelanggaran UniformAccessPrinciple yang dibuat oleh bertrand meyer. Mengapa tidak membuat metode seperti berikut:

public String revision(Item item)
giorgi dvalishvili
sumber
Saya sepenuhnya setuju dengan Anda, bagus !!!!
Irakli Gabisonia
1

Saya biasanya akan menggunakan Getuntuk mengambil sebuah objek / nilai, dan Finduntuk mengambil nya lokasi (dalam array, misalnya).

misalnya:

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

integer i = somearray.Find( 'name');
GrandmasterB
sumber
0

Bagi saya, findmenyiratkan mungkin ada lebih dari satu hasil yang ada. getmenyiratkan hanya satu.

Karl Bielefeldt
sumber
8
Sepertinya memiliki perasaan itu, tapi aku tidak yakin aku sepenuhnya setuju. Pikirkan cara ini: getCatvs findCatvs getCatsvs findCats. Yang find..masih merupakan benda tunggal yang dikembalikan. Jamak harus ditambahkan ke kata benda, menurut pendapat saya.
knownasilya