Ide dasar di balik OOP adalah bahwa data dan perilaku (berdasarkan data itu) tidak dapat dipisahkan dan mereka digabungkan oleh gagasan objek kelas. Objek memiliki data dan metode yang bekerja dengan itu (dan data lainnya). Jelas dengan prinsip-prinsip OOP, objek yang hanya data (seperti C struct) dianggap sebagai anti-pola.
Sejauh ini bagus.
Masalahnya adalah saya telah memperhatikan bahwa kode saya tampaknya akan semakin ke arah pola-anti ini akhir-akhir ini. Tampak bagi saya bahwa semakin saya mencoba untuk mendapatkan informasi yang bersembunyi di antara kelas-kelas dan desain yang digabungkan secara longgar, semakin banyak kelas saya yang menjadi campuran data murni tanpa kelas perilaku dan semua perilaku tanpa kelas data.
Saya biasanya merancang kelas dengan cara yang meminimalkan kesadaran mereka tentang keberadaan kelas lain dan meminimalkan pengetahuan mereka tentang antarmuka kelas lain. Saya terutama menegakkan ini dengan cara top-down, kelas tingkat bawah tidak tahu tentang kelas tingkat yang lebih tinggi. Misalnya:
Misalkan Anda memiliki API permainan kartu umum. Anda memiliki kelas Card. Sekarang Cardkelas ini perlu menentukan visibilitas ke pemain.
Salah satunya adalah dengan memiliki boolean isVisible(Player p)di Cardkelas.
Lain adalah memiliki boolean isVisible(Card c)di Playerkelas.
Saya tidak menyukai pendekatan pertama khususnya karena memberikan pengetahuan tentang Playerkelas tingkat yang lebih tinggi ke kelas tingkat yang lebih rendah Card.
Sebagai gantinya saya memilih opsi ketiga di mana kita memiliki Viewportkelas yang, diberikan Playerdan daftar kartu menentukan kartu mana yang terlihat.
Namun pendekatan ini merampas baik Carddan Playerkelas dari fungsi anggota yang mungkin. Setelah Anda melakukan ini untuk hal-hal lain selain visibilitas kartu, Anda dibiarkan dengan Carddan Playerkelas - kelas yang berisi data murni karena semua fungsi diimplementasikan di kelas-kelas lain, yang sebagian besar kelas tanpa data, hanya metode, seperti di Viewportatas.
Ini jelas bertentangan dengan gagasan utama OOP.
Mana cara yang benar? Bagaimana saya harus pergi tentang tugas meminimalkan interdependensi kelas dan meminimalkan asumsi pengetahuan dan penggabungan, tetapi tanpa menutup dengan desain aneh di mana semua kelas tingkat rendah hanya berisi data dan kelas tingkat tinggi berisi semua metode? Adakah yang punya solusi atau perspektif ketiga tentang desain kelas yang menghindari seluruh masalah?
PS Berikut contoh lain:
Misalkan Anda memiliki kelas DocumentIdyang tidak berubah, hanya memiliki satu BigDecimal idanggota dan pengambil untuk anggota ini. Sekarang Anda perlu memiliki metode di suatu tempat, yang memberikan DocumentIdpengembalian Documentuntuk id ini dari database.
Apakah kamu:
- Tambahkan
Document getDocument(SqlSession)metode keDocumentIdkelas, tiba-tiba memperkenalkan pengetahuan tentang kegigihan Anda ("we're using a database and this query is used to retrieve document by id"), API yang digunakan untuk mengakses DB dan sejenisnya. Juga kelas ini sekarang membutuhkan file JAR persistensi hanya untuk mengkompilasi. - Tambahkan beberapa kelas lain dengan metode
Document getDocument(DocumentId id), meninggalkanDocumentIdkelas sebagai mati, tidak ada perilaku, kelas struct-seperti.