Sebagai contoh, misalkan Anda memiliki program permainan konsol, yang memiliki semua jenis metode input / output ke dan dari konsol. Apakah akan pintar untuk menjaga mereka semua dalam satu inputOutput
kelas atau istirahat mereka turun ke kelas khusus lebih seperti startMenuIO
, inGameIO
, playerIO
, gameBoardIO
, dll sehingga setiap kelas memiliki sekitar 1-5 metode?
Dan pada catatan yang sama, jika lebih baik untuk memecahnya, akankah pintar untuk menempatkan mereka di IO
namespace sehingga membuat memanggil mereka sedikit lebih bertele-tele, misalnya: IO.inGame
dll?
Jawaban:
Perbarui (rekap)
Karena saya telah menulis jawaban yang agak bertele-tele, inilah yang akhirnya menjadi:
inGameIO
danplayerIO
kelas kemungkinan merupakan pelanggaran SRP. Kemungkinan itu berarti Anda menggabungkan cara Anda menangani IO dengan logika aplikasi.Saya pikir Anda melihat ini dengan cara yang salah. Anda memisahkan fungsi IO dalam komponen aplikasi, sedangkan - untuk lebih masuk akal untuk memiliki kelas IO terpisah berdasarkan sumber, dan "jenis" IO.
Memiliki beberapa
KeyboardIO
kelas dasar / generikMouseIO
untuk memulai, dan kemudian berdasarkan kapan dan di mana Anda membutuhkannya, memiliki subkelas yang menangani kata IO secara berbeda.Misalnya, input teks adalah sesuatu yang mungkin ingin Anda tangani secara berbeda untuk kontrol dalam game. Anda akan menemukan diri Anda ingin memetakan kunci tertentu secara berbeda tergantung pada setiap kasus penggunaan, tetapi pemetaan itu bukan bagian dari IO itu sendiri, melainkan bagaimana Anda menangani IO.
Berpegang teguh pada SRP, saya akan memiliki beberapa kelas yang dapat saya gunakan untuk keyboard IO. Bergantung pada situasinya, saya mungkin ingin berinteraksi dengan kelas-kelas ini secara berbeda, tetapi satu-satunya tugas mereka adalah memberi tahu saya apa yang dilakukan pengguna.
Saya kemudian akan menyuntikkan objek-objek ini ke objek handler yang akan memetakan IO mentah ke sesuatu yang logika aplikasi saya dapat bekerja dengan (misalnya: pengguna menekan "w" , handler memetakan itu ke
MOVE_FORWARD
).Penangan ini, pada gilirannya digunakan untuk membuat karakter bergerak, dan menggambar layar sesuai. Penyederhanaan yang terlalu berlebihan, tetapi intinya adalah struktur seperti ini:
Apa yang kita miliki sekarang adalah kelas yang bertanggung jawab atas IO keyboard dalam bentuk mentahnya. Kelas lain yang menerjemahkan data ini menjadi sesuatu yang benar-benar masuk akal oleh mesin permainan, data ini kemudian digunakan untuk memperbarui status semua komponen yang terlibat, dan akhirnya, kelas yang terpisah akan menangani output ke layar.
Setiap kelas memiliki satu pekerjaan: menangani input keyboard dilakukan oleh kelas yang tidak tahu / peduli / harus tahu apa arti input yang diprosesnya. Yang perlu dilakukan adalah mengetahui cara mendapatkan input (buffered, unbuffered, ...).
Pawang menerjemahkan ini ke dalam representasi internal untuk sisa aplikasi untuk memahami info ini.
Mesin permainan mengambil data yang telah diterjemahkan, dan menggunakannya untuk memberi tahu semua komponen yang relevan bahwa sesuatu sedang terjadi. Masing-masing komponen melakukan hanya satu hal, apakah itu pemeriksaan tabrakan, atau perubahan karakter animasi, tidak masalah, itu tergantung pada masing-masing objek.
Objek-objek ini kemudian menyampaikan keadaannya kembali, dan data ini diteruskan ke
Game.Screen
, yang pada dasarnya adalah penangan IO terbalik. Ini memetakan representasi internal ke sesuatu yangIO.Screen
dapat digunakan komponen untuk menghasilkan output yang sebenarnya.sumber
IO
dangame
ruang nama atau kelas dengan subclass?Prinsip tanggung jawab tunggal bisa sulit dipahami. Apa yang menurut saya bermanfaat adalah menganggapnya seperti bagaimana Anda menulis kalimat. Anda tidak mencoba menjejalkan banyak ide menjadi satu kalimat. Setiap kalimat harus menyatakan satu ide dengan jelas dan menunda detailnya. Misalnya, jika Anda ingin mendefinisikan mobil, Anda akan mengatakan:
Maka Anda akan mendefinisikan hal-hal seperti "kendaraan", "jalan", "roda", dll. Secara terpisah. Anda tidak akan mencoba mengatakan:
Demikian juga, Anda harus mencoba membuat kelas, metode, dll., Nyatakan konsep sentral sesederhana mungkin dan tunda detailnya ke metode dan kelas lain. Sama seperti dengan menulis kalimat, tidak ada aturan keras tentang seberapa besar seharusnya.
sumber
Saya akan mengatakan bahwa cara terbaik untuk pergi adalah menjaga mereka di kelas yang terpisah. Kelas kecil tidak buruk, bahkan sebagian besar waktu itu adalah ide bagus.
Mengenai kasus spesifik Anda, saya pikir memiliki pemisahan dapat membantu Anda mengubah logika dari salah satu penangan tertentu tanpa mempengaruhi yang lain dan, jika perlu, akan lebih mudah bagi Anda untuk menambahkan metode input / output baru jika itu yang terjadi.
sumber
Kepala Satu Tanggung Jawab menyatakan bahwa suatu kelas hanya boleh memiliki satu alasan untuk berubah. Jika kelas Anda memiliki banyak alasan untuk berubah, maka Anda dapat membaginya menjadi kelas lain dan memanfaatkan komposisi untuk menghilangkan masalah ini.
Untuk menjawab pertanyaan Anda, saya harus bertanya kepada Anda: Apakah kelas Anda hanya memiliki satu alasan untuk berubah? Jika tidak, maka jangan takut untuk terus menambahkan kelas khusus sampai masing-masing hanya memiliki satu alasan untuk berubah.
sumber