Berikut ini persyaratan yang disederhanakan:
Pengguna membuat
Question
dengan beberapaAnswer
s.Question
harus memiliki setidaknya satuAnswer
.Klarifikasi: pikirkan
Question
danAnswer
seperti dalam ujian : ada satu pertanyaan, tetapi beberapa jawaban, di mana hanya sedikit yang benar. Pengguna adalah aktor yang sedang mempersiapkan tes ini, maka ia menciptakan pertanyaan dan jawaban.
Saya mencoba memodelkan contoh sederhana ini agar 1) mencocokkan model kehidupan nyata 2) agar ekspresif dengan kode, sehingga untuk meminimalkan potensi penyalahgunaan dan kesalahan, dan untuk memberikan petunjuk kepada pengembang cara menggunakan model.
Pertanyaan adalah entitas , sedangkan jawaban adalah objek nilai . Pertanyaan memiliki jawaban. Sejauh ini, saya punya solusi yang memungkinkan.
[A] Pabrik di dalamQuestion
Alih-alih membuat Answer
secara manual, kita dapat memanggil:
Answer answer = question.createAnswer()
answer.setText("");
...
Itu akan membuat jawaban dan menambahkannya ke pertanyaan. Kemudian kita dapat memanipulasi jawaban dengan mengatur propertinya. Dengan cara ini, hanya pertanyaan yang dapat memberikan jawaban. Selain itu, kami mencegah mendapat jawaban tanpa pertanyaan. Namun, kami tidak memiliki kendali atas menciptakan jawaban, karena itu di-hardcode di Question
.
Ada juga satu masalah dengan 'bahasa' kode di atas. Pengguna adalah orang yang menciptakan jawaban, bukan pertanyaan. Secara pribadi, saya tidak suka kita membuat objek nilai dan bergantung pada pengembang untuk mengisinya dengan nilai - bagaimana dia bisa yakin apa yang harus ditambahkan?
[B] Pabrik di dalam Pertanyaan, ambil nomor 2
Beberapa mengatakan kita harus memiliki metode semacam ini di Question
:
question.addAnswer(String answer, boolean correct, int level....);
Mirip dengan solusi di atas, metode ini mengambil data wajib untuk jawabannya dan membuat yang juga akan ditambahkan ke pertanyaan.
Masalahnya di sini adalah bahwa kita menduplikasi konstruktor Answer
tanpa alasan yang bagus. Juga, apakah pertanyaan benar-benar menciptakan jawaban?
[C] dependensi konstruktor
Mari kita bebas membuat kedua objek dengan diri kita sendiri. Mari kita juga mengekspresikan dependensi yang tepat dalam konstruktor:
Question q = new Question(...);
Answer a = new Answer(q, ...); // answer can't exist without a question
Ini memberikan petunjuk kepada pengembang, karena jawaban tidak dapat dibuat tanpa pertanyaan. Namun, kami tidak melihat 'bahasa' yang mengatakan bahwa jawaban itu 'ditambahkan' ke pertanyaan. Di sisi lain, apakah kita benar-benar perlu melihatnya?
[D] Constructor ketergantungan, mengambil # 2
Kita bisa melakukan yang sebaliknya:
Answer a1 = new Answer("",...);
Answer a2 = new Answer("",...);
Question q = new Question("", a1, a2);
Ini adalah situasi yang berlawanan di atas. Di sini jawaban bisa ada tanpa pertanyaan (yang tidak masuk akal), tetapi pertanyaan tidak bisa ada tanpa jawaban (yang masuk akal). Juga, 'bahasa' di sini lebih jelas tentang pertanyaan itu yang akan memiliki jawabannya.
[E] Cara umum
Inilah yang saya sebut cara umum, hal pertama yang biasanya dilakukan ppl:
Question q = new Question("",...);
Answer a = new Answer("",...);
q.addAnswer(a);
yang merupakan versi 'longgar' dari dua jawaban di atas, karena baik jawaban maupun pertanyaan mungkin ada tanpa satu sama lain. Tidak ada petunjuk khusus bahwa Anda harus mengikat mereka bersama.
[F] Gabungan
Atau saya harus menggabungkan C, D, E - untuk mencakup semua cara bagaimana hubungan dapat dibuat, sehingga untuk membantu pengembang untuk menggunakan apa pun yang terbaik untuk mereka.
Pertanyaan
Saya tahu orang dapat memilih salah satu jawaban di atas berdasarkan 'firasat'. Tapi saya ingin tahu apakah ada varian di atas yang lebih baik dari yang lain dengan alasan yang bagus Juga, tolong jangan berpikir di dalam pertanyaan di atas, saya ingin memeras di sini beberapa praktik terbaik yang dapat diterapkan pada kebanyakan kasus - dan jika Anda setuju, sebagian besar kasus penggunaan penciptaan beberapa entitas serupa. Juga, mari kita menjadi agnostik teknologi di sini, misalnya. Saya tidak ingin berpikir apakah ORM akan digunakan atau tidak. Hanya ingin mode ekspresif yang bagus.
Adakah kebijaksanaan tentang hal ini?
EDIT
Harap abaikan properti lain dari Question
dan Answer
, mereka tidak relevan untuk pertanyaan. Saya mengedit teks di atas dan mengubah sebagian besar konstruktor (bila perlu): sekarang mereka menerima nilai properti yang diperlukan. Itu mungkin hanya string pertanyaan, atau peta string dalam bahasa yang berbeda, status dll - properti apa pun yang dilewati, mereka bukan fokus untuk ini;) Jadi anggap saja kita di atas melewati parameter yang diperlukan, kecuali dikatakan berbeda. Terima kasih!
sumber
addAnswer
atauassignAnswer
akan menjadi bahasa yang lebih baik daripada hanyaanswer
, saya harap Anda setuju dengan ini. Lagi pula, pertanyaan saya adalah - apakah Anda masih memilih B dan misalnya memiliki salinan sebagian besar argumen dalam metode jawaban? Bukankah itu duplikasi?Answer
adalah objek nilai, itu akan disimpan dengan akar agregat dari agregatnya. Anda tidak menyimpan objek nilai secara langsung, Anda juga tidak menyimpan entitas jika mereka bukan akar dari agregatnya.Jika persyaratannya sangat sederhana, ada beberapa kemungkinan solusi, maka prinsip KISS harus diikuti. Dalam kasus Anda, itu akan menjadi opsi E.
Ada juga kasus membuat kode yang mengekspresikan sesuatu, yang seharusnya tidak. Misalnya mengikat pembuatan Jawaban atas Pertanyaan (A dan B) atau memberikan referensi Jawaban ke Pertanyaan (C dan D) menambahkan beberapa perilaku yang tidak perlu ke domain dan mungkin membingungkan. Juga, dalam kasus Anda, Pertanyaan kemungkinan besar adalah agregat dengan Jawaban dan Jawaban akan menjadi tipe nilai.
sumber
Saya akan memilih [C] atau [E].
Pertama, mengapa tidak A dan B? Saya tidak ingin Pertanyaan saya bertanggung jawab untuk menciptakan nilai terkait. Bayangkan jika Pertanyaan memiliki banyak objek bernilai lainnya - apakah Anda akan memasukkan
create
metode untuk setiap objek bernilai ? Atau jika ada beberapa agregat kompleks, hal yang sama.Kenapa tidak [D]? Karena itu berlawanan dengan apa yang kita miliki di alam. Kami pertama kali membuat Pertanyaan. Anda dapat membayangkan halaman web tempat Anda membuat semua ini - pengguna pertama kali akan membuat pertanyaan, bukan? Karena itu, bukan D.
[E] KISS, seperti yang dikatakan @Euphoric. Tapi saya juga mulai menyukai [C] baru-baru ini. Ini tidak begitu membingungkan seperti yang terlihat. Selain itu, bayangkan jika Pertanyaan tergantung pada lebih banyak hal - maka pengembang harus tahu apa yang perlu dimasukkan ke dalam Pertanyaan agar diinisialisasi dengan benar. Meskipun Anda benar - tidak ada bahasa 'visual' yang menjelaskan bahwa jawaban sebenarnya ditambahkan ke pertanyaan.
Bacaan tambahan
Pertanyaan seperti ini membuat saya bertanya-tanya apakah bahasa komputer kita terlalu umum untuk pemodelan. (Saya mengerti mereka harus generik untuk menjawab semua persyaratan pemrograman). Baru-baru ini saya mencoba menemukan cara yang lebih baik untuk mengekspresikan bahasa bisnis menggunakan antarmuka yang lancar. Sesuatu seperti ini (dalam bahasa sudo):
yaitu mencoba untuk beralih dari kelas * Layanan dan * Repositori besar ke bagian yang lebih kecil dari logika bisnis. Hanya sebuah ide.
sumber
Saya yakin Anda melewatkan satu poin di sini, akar Agregat Anda harus menjadi Entitas Tes Anda.
Dan jika itu benar-benar terjadi, saya percaya TestFactory akan paling cocok untuk menjawab masalah Anda.
Anda akan mendelegasikan bangunan Pertanyaan dan Jawaban ke Pabrik dan karena itu Anda pada dasarnya dapat menggunakan solusi apa pun yang Anda pikirkan tanpa merusak model Anda karena Anda bersembunyi kepada klien seperti cara Anda instantiate sub entitas Anda.
Ini, selama TestFactory adalah satu-satunya antarmuka yang Anda gunakan untuk instantiate Tes Anda.
sumber