Haruskah daftar parameter metode berisi objek atau pengidentifikasi objek?

10

Tim kami mengadakan diskusi berikut:

Katakanlah kita memiliki dua metode berikut:

public Response Withdraw(int clubId, int terminalId,int cardId, string invoice, decimal amount);

public Response Withdraw(Club club, Terminal terminal,Card card, string invoice, decimal amount);

apa yang dikirim over-the-wire hanyalah id.

satu pihak mengatakan bahwa metode pertama benar, karena kita hanya memiliki id terminal dan klub, dan harus jelas bahwa kita tidak memiliki yang lain, ini adalah pendekatan saya.

pihak lain mengatakan bahwa metode kedua benar karena lebih fleksibel.

Kita terbiasa dengan gagasan parameter objek, di sisi lain juga berpikir bahwa parameter objek harus memiliki objek sebagai properti.

Mana pendekatan yang benar?

Mungkin ada pendekatan ketiga yang lebih baik?

Mithir
sumber
Apa? ...........
James
1
Konteks? Layanan web? WCF?
CodesInChaos
1
@ James - maaf saya menulis pertanyaan ini agak cepat, dapatkah Anda memberi tahu saya apa yang tidak dimengerti sehingga saya dapat mengeditnya?
Mithir
@CodesInChaos metode adalah metode BL sebenarnya
Mithir

Jawaban:

10

Jawabannya tergantung konteks.

Jika klien diharapkan sudah memiliki semua objek tersebut , saya akan menggunakan parameter objek. Kalau tidak, kode mereka akan terlihat lebih berbelit-belit daripada yang seharusnya. (Misalnya, mereka akan memiliki panggilan seperti club.getId(), misalnya.)

Jika klien hanya akan memiliki id yang tersedia dengan mudah, maka mungkin pendekatan kedua lebih baik, karena Anda mungkin tidak ingin klien harus merakit / memuat semua objek jika Anda benar-benar hanya membutuhkan id.

Opsi adalah untuk menyediakan kedua metode , sehingga klien dapat memilih mana yang akan digunakan (mengingat bahwa ini tidak mengacaukan API Anda)

Secara umum parameter objek lebih dapat diperluas, karena jika di masa depan Anda membutuhkan data lain untuk melakukan pekerjaan, Anda tidak perlu memperkenalkan metode lain yang mengambil info tambahan.

Terakhir, tanda tangan metode Anda tidak boleh ditentukan oleh hal-hal spesifik yang dilakukan metode tersebut (dalam kasus Anda, apa yang sebenarnya terjadi di atas kawat). API harus masuk akal secara abstrak sehingga jika implementasi berubah, Anda tidak kacau.

c_maker
sumber
3
+1 Saya hanya akan menambahkan satu poin lagi: untuk metode yang disebut jarak jauh ("over the wire"?), Objek yang lewat dapat memerlukan serialisasi pohon objek yang luas. ID adalah pengganti yang sangat baik untuk objek ketika Anda khawatir tentang ukuran muatan panggilan jarak jauh.
Ross Patterson
1
Dalam hal ini sepertinya Anda digabungkan ke serangkaian abstraksi sehingga melewati Id tidak akan memberi Anda lebih banyak fleksibilitas dan mungkin akan meningkatkan kemungkinan Anda membalikkan parameter. Pertanyaannya adalah seberapa erat kode dalam metode ini ditambah dengan abstraksi yang saya sampaikan? Misalnya metode seperti "validateCreditCard (kartu string, string cvi)" mungkin harus tetap dengan primitif untuk menghindari tergabung erat dengan semacam objek CreditCard.
ipaul
Saya akan bertemu di tengah dan menggunakan antarmuka dalam daftar parameter. Maka klub Anda bisa menjadi klub, tetapi juga sauna di masa depan.
Pieter B
13

Pendekatan pertama adalah indikasi Obsesi Primitif . Karena Anda melewatkan int dan string, sangat mudah bagi programmer untuk membuat kesalahan (misalnya mengirimkan clubId ke parameter terminalId). Ini akan menghasilkan bug yang sulit ditemukan.

Dalam contoh kedua, tidak mungkin untuk lulus klub ketika terminal diharapkan - ini akan memberi Anda kesalahan waktu kompilasi.

Meski begitu, saya masih akan melihat string invoice. Apakah faktur benar-benar sebuah string? Apa amountartinya Ini lebih cenderung nilai moneter.

Anda menyebutkan dalam pertanyaan Anda "apa yang dikirim lewat kabel hanyalah id.". Ini benar, tetapi jangan biarkan persyaratan ini memperkeruh domain Anda.

Penjelasan terbaik yang saya lihat dalam mendukung pendekatan ini adalah dalam aturan 3 dari Object Calisthenics :

Int itu sendiri hanyalah skalar, jadi tidak ada artinya. Ketika suatu metode mengambil int sebagai parameter, nama metode perlu melakukan semua pekerjaan mengekspresikan maksud. Jika metode yang sama menggunakan Hour sebagai parameter, akan lebih mudah untuk melihat apa yang terjadi. Objek kecil seperti ini dapat membuat program lebih mudah dikelola, karena tidak mungkin untuk melewatkan Tahun ke metode yang menggunakan parameter Hour. Dengan variabel primitif kompiler tidak dapat membantu Anda menulis program yang benar secara semantik. Dengan sebuah objek, bahkan yang kecil, Anda memberikan kompiler dan programmer informasi tambahan tentang apa nilainya dan mengapa itu digunakan.

MattDavey
sumber
Jadi pendekatan kedua lebih disukai? bahkan jika ada objek klub dengan hanya properti id yang diisi?
Mithir
Ini tampaknya merupakan blog acak. Tidak ada bukti untuk mengatakan apa yang disukai. Siapa yang peduli benar-benar apa yang disukai? Lakukan apa yang berhasil untuk Anda
James
@ James Tidak ada jawaban pasti untuk pertanyaan ini, terutama karena OP belum memberi kami banyak konteks. Siapa pun yang dengan tegas mengklaim bahwa satu pendekatan lebih disukai daripada yang lain adalah melakukan OP merugikan. Bukan hitam dan putih.
MattDavey
1
@ James, saya hanya menunjukkan bahwa pendekatan pertama membuatnya sangat mudah untuk memperkenalkan kesulitan untuk menemukan bug. Saya tidak mengatakan tipe primitif itu buruk, tetapi tujuan tipe primitif adalah untuk membangun tipe domain yang bermakna. Menggunakannya di luar konteks ini adalah definisi utama dari bau kode obsesi primitif.
MattDavey
5
@ James: Apa yang MattDavey katakan adalah fakta mapan. Dia tidak mengatakan bahwa tipe asli itu buruk, apa yang dia katakan bahwa ini: someMethod (int, int, int, string, desimal) jauh lebih sulit untuk dipahami dan digunakan oleh klien daripada metode tertentu (Club, Terminal, Card, String, , desimal)
c_maker
2

Tidak ada jawaban yang tepat untuk ini. Pilihan mana pun bisa tepat untuk pekerjaan itu. Yah hampir bagaimanapun, argumen faktur mengangkat alis di alis saya, saya tidak tahu apa itu dari membaca kode.

Jika Anda mengirim id, maka kedua sistem harus dipasangkan dengan erat pada apa yang diwakilinya. ClubID adalah kunci dalam tabel klub. Lebih penting lagi, baik penelepon dan callee perlu menyetujui apa yang disebut tabel Clubs dan basis data yang mana. Jika Anda tidak ingin atau tidak dapat memaksakan kendala itu, maka Anda akan meneruskan objek menggunakan beberapa deskripsi umum, asli, serial, xml, nama = nilai apa pun, file ini :)

Bahwa ketika Anda mengidentifikasi akan dikenakan biaya "melalui kabel". Menghindari itu hanya dengan mengirimkan biaya pengidentifikasi Anda di tempat lain. Jadi yang mana yang paling tidak menyakitimu, sekarang (atau mungkin nanti ...) adalah indikator baik vs buruk.

Tony Hopkinson
sumber