Identifier vs objek domain sebagai parameter metode


10

Apakah ada argumen objektif untuk atau menentang penggunaan objek vs ID unik sebagai parameter metode / fungsi? (dan anggota benda lainnya?). Khususnya dalam konteks bahasa yang diketik secara statis (C # / Java / Scala)

Kelebihan objek itu sendiri:

  • Lebih banyak panggilan aman. Dengan ID ada risiko pemesanan argumen yang salah. Ini dapat dikurangi meskipun dengan menjaga kelas 'mini' untuk setiap kelas yang hanya menyimpan ID dari kelas itu.
  • Dapatkan sekali dari ketekunan, tidak perlu mendapatkan lagi
  • Dengan ID, jika tipe id berubah, katakan int -> long, maka akan membutuhkan perubahan di papan dengan kemungkinan kesalahan .. (courtsey: https://softwareengineering.stackexchange.com/a/284734/145808 )

Kelebihan menggunakan ID:

  • Sebagian besar waktu tidak perlu untuk objek yang sebenarnya, hanya uniqueid akan lakukan, jadi memiliki ID menghemat waktu dari mendapatkannya dari kegigihan.

Campuran teknik-teknik ini, sejauh yang saya bisa lihat, hanya akan memiliki kekurangan dan kelebihan dari keduanya.

Mengingat bahwa ini adalah masalah yang didefinisikan secara konkret, saya harap ada jawaban yang objektif dan bukan- "Saya pikir" atau "Saya suka" jenis ... :-).

EDIT: Konteks pada saran dari komentator- Satu-satunya batasan adalah bahasa yang diketik secara statis. Aplikasi ini adalah aplikasi tujuan umum, meskipun senang mendapatkan jawaban berdasarkan skenario penggunaan khusus juga.

EDIT: Beberapa konteks lagi. Katakanlah saya memiliki sistem manajemen buku. Model saya adalah:

Book: { id: Int, isbn: String, donatedBy: Member, borrowedBy: Member }
Member: {id: Int, name: String}

Table- wishlist: { isbn: String, memberId: Int}
Table- borrows:  { id: Int, memberId: Int}  

Method: 
isInWishList( book: Book, member: Member ) vs isInWishList( bookId: Int,  memberId: Int)

handleBorrowRequest( memberId: Int, book: Book ){ 
   //the login system doesn't actually get the entire member structure, only the member id. I don't need the full member yet. can run a query to verify that the memberId has less than max allowed books for borrowing. 
}

Mengapa saya ingin hanya menyimpan id dan bukan anggota penuh? Katakanlah ketika saya mendapat info tentang buku, saya jarang perlu tahu tentang siapa yang menyumbangkan atau meminjamnya. Mendapatkan informasi lengkap mereka untuk mengisi bidang yang disumbangkan oleh dan dipinjam oleh saya adalah suatu keharusan.

Tentu, ini hanya poin saya. Saya yakin saya kehilangan hal-hal sehingga ingin tahu apa poin yang mendukung / menentang.


Bisakah Anda mengedit pertanyaan Anda dengan lebih banyak konteks? Tidak jelas skenario apa yang ada. Saya akan menebak bahwa Anda berbicara tentang objek yang dikelola oleh sistem ORM (seperti Hibernate) dan bahwa dengan "mini-class" yang Anda maksud adalah proxy-object malas-loading.
Darien


Menambahkan sebagai komentar di sini (hingga saya bisa mendapatkan konteks yang cukup untuk meluas ke jawaban berfitur lengkap): Kecuali jika Anda mengkode nilai-nilai ID dalam kode Anda (sebuah no-no besar), Anda masih harus memuat nilai ID Anda dari suatu tempat kan? "Sebagian besar waktu" juga IMHO cukup samar ...
hjk

@ hjk Menambahkan beberapa konteks lagi, terima kasih. Anda memiliki titik - Anda masih harus memuat nilai ID dari suatu tempat. Namun, ini bukan tentang tidak 'menyentuh' DB tetapi tentang meminimalkan penggunaan dan bandwidth ke DB. Saya bisa mendapatkan id dari semua orang yang ingin meminjam buku, tetapi sebenarnya mendapatkan rincian lengkapnya tidak perlu.
0

Tampaknya itu akan tergantung pada beberapa hal: (1) apakah kasus penggunaan memerlukan atribut aktual (kolom) atau hanya ID, yang tergantung pada kasus penggunaan itu sendiri; (2) apakah Anda menggunakan beberapa caching atau teknik peningkatan kinerja yang akan membuat query ID-to-atribut mudah, dan apakah kasus penggunaan Anda akan cukup berat untuk memecahkan skema caching seperti itu.
rwong

Jawaban:


8

Bergantung pada lingkungan dan konteks masalah Anda, kebutuhan untuk pergi ke basis data dapat dikurangi, dan sebagai hasilnya (IMO) argumen untuk menggunakan id saja hilang.

Sebagai contoh, PHP's Doctrine2 ORM memiliki EntityManager::getReferenceyang menghasilkan proxy yang dimuat malas ke entitas menggunakan id yang disediakan; Saya tidak tahu berapa banyak ORM lain yang melakukan itu, tetapi kira-kira cocok dengan "kelas mini" yang Anda sebutkan. Untuk sebagian besar maksud dan tujuan, ini adalah entitas yang sepenuhnya terhidrasi, sehingga Anda dapat menyebarkannya dan menggunakannya seperti yang lain.

Satu-satunya kasus di mana itu bukan adalah ketika itu diberikan id tidak valid, dan dalam hal itu Anda ingin pergi ke database untuk memvalidasi; ditambah, untuk mengurangi biaya mendapatkan entitas, sebagian besar ORM memiliki fungsionalitas caching (tingkat pertama & kedua) yang tersedia dalam beberapa bentuk.

Setelah kami mengurangi kebutuhan dan biaya untuk pergi ke basis data, kami memiliki sebagian besar keuntungan menggunakan entitas sebagai parameter:

  1. Ketik keamanan.
  2. Kurang pengetahuan yang dibutuhkan oleh penelepon. Pengembang 6 bulan ke depan tidak dapat secara keliru memasukkan id dari entitas yang salah.
  3. Mengurangi biaya refactoring. Jika suatu metode diubah untuk membutuhkan 2 buah informasi dari entitas, tidak ada biaya dalam mengubah penelepon untuk menyediakannya, dengan anggapan penelepon mendapatkan entitas yang sepenuhnya terhidrasi untuk memulai.
  4. Kurang validasi diperlukan per metode. Banyak metode dapat mengasumsikan bahwa entitas yang mereka berikan ada dalam database (karena berasal dari ORM), sehingga tidak perlu lagi memvalidasi id.
  5. (Berpotensi) lebih sedikit panggilan basis data. Jika Anda meneruskan id ke 3 metode, dan masing-masing harus memvalidasi atau mengambil lebih banyak data pada entitas, itu 3 kali lebih banyak panggilan basis data sebagai 1 metode mengambil entitas dan 2 beroperasi di atasnya.

Tentu saja, ada kasus-kasus di mana seseorang mungkin ingin memberikan id saja: misalnya ketika melintasi batas konteks yang dibatasi (dalam desain domain-driven berbicara). Jika kami mempertimbangkan dua konteks terikat dengan gagasan berbeda tentang apa yang membentuk akun (mis. Hubungan keuangan vs pelanggan), maka kami tidak dapat meneruskan akun konteks A ke konteks B. Sebaliknya, id akun (dalam bahasa domain) dapat dilewati.


Caching tidak akan skala dengan baik dengan beberapa contoh aplikasi berjalan. Saya memiliki caching sendiri di tempatnya. Poinnya sangat bagus.
0

Saya kira satu hal lagi terhadap ID adalah bahwa menggunakan ID menyiratkan ketekunan pemanggilan selain validasi, untuk benar-benar mendapatkan objek juga.
0

3

Untuk pertanyaan seperti ini, saya mendelegasikan solusi mana yang paling baik mengkomunikasikan maksud saya sebagai seorang programmer, dan menjadikan pekerjaan "Future Greg" termudah.

Menggunakan objek sebagai argumen membuatnya lebih mudah untuk mendapatkan panggilan metode yang benar 6 bulan dari sekarang dan saya lupa rincian kasar dari aplikasi ini. Untuk membangun "buku ini dalam contoh daftar harapan orang ini", katakanlah isInWishListmetode ini hanya perlu membandingkan Bilangan bulat buku dan anggota. Pada kenyataannya, metode yang satu ini hanya membutuhkan dua bagian data untuk melakukan tugasnya. Sekarang mari kita mundur dari metode yang satu ini, dan lihat keseluruhan sistem perangkat lunak. Saya ragu itu hanya membutuhkan Id buku dan Id anggota untuk dapat beroperasi. Anda akan menarik buku lengkap dan anggota dari basis data sebelum memanggilnya isInWishListkarena kemungkinan Anda perlu melakukan sesuatu lebih dari sekadar memanggil metode yang satu ini. Mungkin Anda melakukannya, tetapi sebagian besar kali Anda perlu melakukan lebih banyak.

Karena itu, Anda tidak secara realistis akan dikenakan penalti kinerja dengan mengambil dan memetakan kedua objek secara penuh dari database. Secara teoritis Anda akan memerlukan lebih sedikit panggilan basis data, tetapi dalam praktiknya Anda akan menemukan bahwa ini tidak benar. Jika Anda melewatkan Id tersebut sebagai parameter dalam string kueri kembali ke server, maka ya, Anda hanya perlu mengambil daftar harapan dari database. Tapi ini adalah pandangan yang sangat sempit dari seluruh aplikasi Anda. Akan ada skenario ketika Anda melakukan operasi lain selain memeriksa daftar keinginan --- misalnya, menambahkan buku ke daftar keinginan. Anda tidak ingin menambahkan item duplikat.

Pergi untuk solusi yang paling mudah bagi seorang programmer baru, atau Masa Depan Anda untuk memahami, yaitu untuk lulus Bookdan Memberobjek masuk Hanya setelah menemukan masalah kinerja yang sebenarnya Anda harus benar-benar memperhatikan diri Anda hanya dengan melewati Id.

Atau, kita dapat mengingat bahwa bahasa yang diketik secara statis seperti Java menawarkan kelebihan metode, sehingga Anda dapat memiliki kue dan memakannya juga:

public boolean isInWishList(int bookId, int memberId) {
    // ...
}

public boolean isInWishList(Book book, Member member) {
    return isInWishList(book.getId(), member.getId());
}

Jawaban sebenarnya untuk pertanyaan ini adalah menulis kedua metode, panggil versi integer-only dari versi yang sangat diketik, dan Bob adalah paman Anda.

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.