Haruskah kita mengganti nama metode kelebihan beban?


14

Asumsikan sebuah antarmuka yang mengandung metode ini:

Car find(long id);

List<Car> find(String model);

Apakah lebih baik mengubah nama mereka seperti ini?

Car findById(long id);

List findByModel(String model);

Memang, setiap pengembang yang menggunakan API ini tidak perlu melihat antarmuka untuk mengetahui kemungkinan argumen dari find()metode awal .

Jadi pertanyaan saya lebih umum: Apa manfaat menggunakan metode kelebihan kode dalam karena mengurangi keterbacaan?


4
Metode mana pun dapat diterima selama Anda konsisten.
ChrisF

Ada hubungan antara metode overloading dan overriding. Namun artikel ini mendukung saran Anda - Mungkin menarik: roseindia.net/javatutorials/…
NoChance

Jawaban:


23

Ini adalah masalah yang relatif kecil dibandingkan dengan banyak praktik keterbacaan buruk lainnya yang bisa membuat Anda rentan, jadi saya akan mengatakan bahwa sebagian besar masalah selera bagaimana Anda menyebutkan metode Anda.

Dengan itu, jika Anda akan melakukan sesuatu tentang hal itu, saya akan mengikuti latihan ini:

  • Kelebihan jika ...

    Metode mematuhi hampir kontrak yang sama tetapi hanya beroperasi pada input yang berbeda (bayangkan operator telepon yang dapat mencari akun Anda dengan nomor ID pajak pribadi Anda, nomor akun Anda, atau nama dan ulang tahun Anda). Ini termasuk mengembalikan jenis output yang sama .

  • Gunakan nama yang berbeda jika ...

    Metode melakukan hal-hal yang sangat berbeda atau mengembalikan output yang berbeda (seperti kasus Anda). Anda mungkin mempertimbangkan untuk menggunakan nama yang berbeda jika seseorang mengakses database dan yang lain tidak.

    Selain itu, jika jenis yang dikembalikan berbeda, saya juga akan mengubah kata kerja untuk menunjukkan bahwa:

    Car findById(long id);
    
    List findAllByModel(String model);
    

3
FWIW, saya akan mengatakan itu sedikit lebih kuat: "Metode mematuhi kontrak yang sama persis ..." Yaitu jenis argumen / hitungan tidak masalah - semantik dari pemanggilan fungsi identik terlepas. Jika jenis argumen / jumlah penting, maka Anda tidak boleh kelebihan beban.
mcmcc

4

Saya akan merekomendasikan menggunakan nama yang berbeda, dalam setiap kasus. Mungkin saja suatu saat nanti, Anda ingin menambahkan metode lain, misalnya List<Car> findByMake(String make), berbeda dengan List<Car> findByModel(String model). Jadi tiba-tiba, memanggil semuanya findberhenti masuk akal. Metode Anda juga cenderung lebih tidak sengaja digunakan secara tidak benar, jika nama mereka memberikan lebih banyak informasi tentang bagaimana mereka harus digunakan.


1
Agar adil, ini tidak akan menjadi masalah jika fungsionalitas lebih eksplisit diwakili oleh objek: find(Make val)dan find(Model val). Kemudian, metode kenyamanan seperti findByMake(String val)akan jauh lebih jelas apa yang sebenarnya mereka lakukan. Bagaimanapun, a Stringbukanlah model atau model, jadi metode ini harus menjelaskan apa yang sebenarnya dilakukannya.
Nicole

4

Jika Anda mengganti nama metode, itu tidak lagi akan kelebihan beban. Dalam dan dari dirinya sendiri, overloading tidak selalu membuat kode lebih mudah dibaca, namun dapat membuat implementasi lebih sulit untuk diikuti jika sintaksisnya tidak jelas.

Banyak bahasa menggunakan metode kelebihan muatan sebagai sarana untuk menampilkan antarmuka ke fungsionalitas di mana parameter mungkin opsional dan standar untuk parameter opsional tersirat. Ini terutama berlaku untuk bahasa yang tidak mendukung sintaks parameter default dalam deklarasi metode.

Jadi melakukan ini:

void MyMethod(int param1, int param2 = 10)
{
    ...
}

menyelamatkan Anda dari melakukan ini:

void MyMethod(int param1)
{
    MyMethod(param1, Param2Default);
}

void MyMethod(int param1, int param2)
{
    ....
}

Mengenai yang lebih mudah dibaca, itu benar-benar terjadi pada Anda. Secara pribadi saya lebih suka opsi kedua, terutama ketika daftar parameter menjadi agak panjang, tapi saya kira itu tidak terlalu penting selama Anda konsisten di seluruh API Anda.

Kesulitan dengan overloading datang ketika Anda ingin fungsi yang pada dasarnya melakukan hal yang sama, dan di mana Anda ingin daftar parameternya sama, tetapi tipe pengembaliannya berbeda. Sebagian besar bahasa tidak tahu bagaimana membedakan antara dua metode yang bernama sama, tetapi dengan jenis pengembalian yang berbeda. Pada titik ini, Anda perlu berpikir tentang menggunakan generik, mengubah antarmuka parameter, atau mengganti nama salah satu metode Anda untuk menunjukkan perbedaan dalam tipe pengembalian. Di sinilah keterbacaan bisa menjadi masalah besar, jika Anda tidak puas dengan skema penamaan yang sederhana dan jelas untuk menghadapi situasi seperti ini.

Memberi nama metode kelebihan beban Anda GetSomething()dan GetSomethingEx()tidak akan mengatakan banyak tentang perbedaan di antara metode Anda, terutama jika itu adalah tipe pengembalian yang merupakan satu-satunya perbedaan di antara mereka. Di sisi lain, GetSomethingAsInt()dan GetSomethingAsString()memberi tahu Anda sedikit lebih banyak tentang apa yang dilakukan metode, dan meskipun tidak sepenuhnya kelebihan, lakukan mengindikasikan bahwa kedua metode melakukan hal yang sama, namun mengembalikan jenis nilai yang berbeda. Saya tahu bahwa ada cara lain Anda bisa menyebutkan metode, namun untuk tujuan menggambarkan hal ini, contoh-contoh kasar ini harus dilakukan.

Dalam contoh OPs, penggantian nama tidak sepenuhnya diperlukan karena parameter metode berbeda, namun itu membuat hal-hal sedikit lebih jelas untuk memberi nama metode lebih khusus. Pada akhirnya, itu benar-benar turun ke jenis antarmuka yang ingin Anda presentasikan kepada pengguna Anda. Keputusan untuk tidak membebani tidak harus dibuat hanya berdasarkan persepsi Anda tentang keterbacaan. Metode overloading misalnya dapat menyederhanakan antarmuka API dan mengurangi jumlah metode yang mungkin perlu diingat oleh pengembang, di sisi lain, itu dapat mengaburkan antarmuka hingga derajat yang kemudian mengharuskan pengembang untuk membaca dokumentasi metode untuk memahami bentuk mana metode untuk digunakan, sedangkan memiliki sejumlah metode yang sama namun deskriptif disebutkan dapat membuatnya lebih jelas hanya membaca nama metode untuk tujuannya.


0

Mendukung kelebihan muatan selama metode mengembalikan hal yang sama dan mengikuti kontrak yang sama. Overloading membebaskan kode panggilan dari melakukan yang tidak perlu ke tipe parameter.

Misalkan fungsi panggilan menerima permintaan pencarian sebagai parameter dan melakukan beberapa pemrosesan lain sebelum dan / atau setelah panggilan find.

void tryToSellCars(String which) {
    /* grab an airhorn, inflatable tube guy... */
    List<Car> cars = find(which);
    /* expound virtues of each car in detail... */
}

Jika Anda ingin mengubah jenis kueri itu untuk alasan apa pun (misalnya dari string ID sederhana ke objek kueri berfitur lengkap), Anda dapat membuat perubahan dalam fungsi panggilan hanya dengan mengubah tanda tangan fungsi untuk menerima tipe parameter baru tanpa khawatir tentang mengubah metode yang dipanggilnya di kelas Anda.

void tryToSellCar(CarQuery which) {
    /* grab airhorn, inflate tube guy... */
    List<Car> cars = find(which)
    /* expound virtues of each car in detail... */
}

Jika Anda menerapkan findByIddan findByQueryObjectsecara terpisah, Anda harus memburu setiap panggilan untuk melakukan perubahan itu. Dalam contoh, saya hanya mengubah satu kata dan saya selesai.


Jawaban ini mengasumsikan, tentu saja, bahwa Anda menggunakan bahasa yang mendukung kelebihan beban dengan kesalahan waktu kompilasi untuk parameter yang tidak valid. Jika Anda menulis JavaScript atau Ruby atau bahasa lain apa pun yang tidak secara alami mendukung overloading, saya akan selalu menggunakan verbose findByFoountuk menangkap ketidakcocokan jenis sebelumnya.
sqykly
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.