Baru-baru ini saya berdiskusi dengan seorang teman saya tentang OOP dalam pengembangan video game.
Saya sedang menjelaskan arsitektur dari salah satu game saya yang, yang mengejutkan teman saya, berisi banyak kelas kecil dan beberapa lapisan abstraksi. Saya berpendapat bahwa ini adalah hasil dari saya yang berfokus untuk memberikan segalanya Tanggung Jawab Tunggal dan juga melonggarkan hubungan antar komponen.
Kekhawatirannya adalah bahwa sejumlah besar kelas akan diterjemahkan menjadi mimpi buruk pemeliharaan. Pandangan saya adalah bahwa itu akan memiliki efek sebaliknya. Kami melanjutkan untuk membahas ini selama berabad-abad, akhirnya setuju untuk tidak setuju, mengatakan bahwa mungkin ada kasus di mana prinsip-prinsip SOLID dan OOP yang tepat tidak benar-benar tercampur dengan baik.
Bahkan entri Wikipedia tentang prinsip-prinsip SOLID menyatakan bahwa itu adalah pedoman yang membantu untuk menulis kode yang dapat dipelihara dan bahwa mereka adalah bagian dari strategi keseluruhan pemrograman yang gesit dan adaptif.
Jadi, pertanyaan saya adalah:
Apakah ada kasus di OOP di mana beberapa atau semua prinsip SOLID tidak meminjamkan diri untuk membersihkan kode?
Saya dapat langsung membayangkan bahwa Prinsip Pergantian Liskov mungkin dapat bertentangan dengan rasa pewarisan aman lainnya. Dengan kata lain, jika seseorang menemukan pola bermanfaat lain yang diterapkan melalui pewarisan, sangat mungkin LSP mungkin bertentangan langsung dengannya.
Apakah ada yang lain? Mungkin jenis proyek tertentu atau platform target tertentu bekerja lebih baik dengan pendekatan yang kurang SOLID?
Edit:
Saya hanya ingin menentukan bahwa saya tidak bertanya bagaimana meningkatkan kode saya;) Satu-satunya alasan saya menyebutkan proyek dalam pertanyaan ini adalah untuk memberikan sedikit konteks. Pertanyaan saya adalah tentang OOP dan prinsip-prinsip desain secara umum .
Jika Anda ingin tahu tentang proyek saya, lihat ini .
Edit 2:
Saya membayangkan pertanyaan ini akan dijawab dalam satu dari 3 cara:
- Ya, ada prinsip-prinsip desain OOP yang sebagian bertentangan dengan SOLID
- Ya, ada prinsip-prinsip desain OOP yang sepenuhnya bertentangan dengan SOLID
- Tidak, SOLID adalah lutut lebah dan OOP selamanya akan lebih baik dengan itu. Tapi, seperti semua hal lainnya, ini bukan obat mujarab. Minum dengan bertanggung jawab.
Opsi 1 dan 2 kemungkinan akan menghasilkan jawaban yang panjang dan menarik. Opsi 3, di sisi lain, akan menjadi jawaban yang pendek, tidak menarik, tetapi meyakinkan secara keseluruhan.
Kami tampaknya akan menyatu ke opsi 3.
sumber
Jawaban:
Secara umum, tidak. Sejarah telah menunjukkan bahwa prinsip-prinsip SOLID sebagian besar berkontribusi pada peningkatan decoupling, yang pada gilirannya telah terbukti meningkatkan fleksibilitas dalam kode dan dengan demikian kemampuan Anda untuk mengakomodasi perubahan serta membuat kode lebih mudah untuk dipikirkan, diuji, digunakan kembali .. singkatnya, buat kode Anda lebih bersih.
Sekarang, mungkin ada kasus di mana prinsip-prinsip SOLID bertabrakan dengan KERING (jangan ulangi sendiri), CIUMAN (tetap bodoh, sederhana) atau prinsip-prinsip lain dari desain OO yang baik. Dan tentu saja, mereka dapat berbenturan dengan realitas persyaratan, keterbatasan manusia, keterbatasan bahasa pemrograman kita, hambatan lainnya.
Singkatnya, prinsip-prinsip SOLID akan selalu meminjamkan diri untuk membersihkan kode, tetapi dalam beberapa skenario mereka akan meminjamkan diri mereka sendiri kurang dari alternatif yang saling bertentangan. Mereka selalu baik, tetapi kadang-kadang hal lain lebih baik.
sumber
Count
danasImmutable
, dan properti sepertigetAbilities
[yang kembalinya akan menunjukkan apakah hal-hal sepertiCount
akan "efisien"], maka seseorang dapat memiliki metode statis yang mengambil banyak urutan dan menggabungkannya sehingga mereka akan berperilaku sebagai urutan yang lebih panjang. Jika kemampuan tersebut hadir dalam tipe urutan dasar, bahkan jika mereka hanya rantai ke implementasi standar, maka agregat akan dapat mengekspos kemampuan itu ...Saya pikir saya memiliki perspektif yang tidak biasa dalam hal saya telah bekerja di bidang keuangan dan game.
Banyak programmer yang saya temui dalam permainan sangat buruk di Rekayasa Perangkat Lunak - tetapi mereka tidak perlu berlatih seperti SOLID. Secara tradisional, mereka memasukkan permainan mereka ke dalam kotak - kemudian mereka selesai.
Di bidang keuangan, saya menemukan bahwa pengembang dapat menjadi sangat ceroboh dan tidak disiplin karena mereka tidak memerlukan kinerja yang Anda lakukan dalam permainan.
Kedua pernyataan di atas tentu saja over-generalisasi, tetapi sebenarnya, dalam kedua kasus kode bersih sangat penting. Untuk optimasi kode yang jelas dan mudah dipahami adalah penting. Demi pemeliharaan, Anda menginginkan hal yang sama.
Itu tidak berarti bahwa SOLID bukan tanpa kritik. Mereka disebut prinsip namun mereka harus diikuti seperti pedoman? Jadi kapan tepatnya saya harus mengikuti mereka? Kapan saya harus melanggar peraturan?
Anda mungkin dapat melihat dua potong kode dan mengatakan yang mana yang paling sesuai dengan SOLID. Namun secara terpisah, tidak ada cara obyektif untuk mengubah kode menjadi SOLID. Ini jelas untuk interpretasi pengembang.
Adalah tidak berurutan untuk mengatakan bahwa, "sejumlah besar kelas dapat mengarah pada mimpi buruk pemeliharaan". Namun, jika SRP tidak ditafsirkan dengan benar, Anda dapat dengan mudah berakhir dengan masalah ini.
Saya telah melihat kode dengan banyak lapisan yang tidak bertanggung jawab. Kelas yang tidak melakukan apa pun selain lulus dari satu kelas ke kelas lainnya. Masalah klasik terlalu banyak lapisan tipuan.
SRP jika disalahgunakan dapat berakhir dengan kurangnya kohesi dalam kode Anda. Anda dapat mengetahui hal ini saat Anda mencoba menambahkan fitur. Jika Anda selalu harus mengubah beberapa tempat secara bersamaan, maka kode Anda tidak memiliki kohesi.
Open-Closed bukan tanpa kritik. Misalnya, lihat ulasan Jon Skeet tentang prinsip Open Closed . Saya tidak akan mereproduksi argumennya di sini.
Argumen Anda tentang LSP tampaknya agak hipotetis dan saya tidak benar-benar mengerti apa yang Anda maksud dengan bentuk pewarisan aman lainnya?
ISP sepertinya menduplikasi SRP. Tentunya mereka harus ditafsirkan sama karena Anda tidak pernah dapat mengantisipasi apa yang akan dilakukan semua klien dari antarmuka Anda. Antarmuka kohesif hari ini adalah pelanggar ISP besok. Satu-satunya kesimpulan yang tidak masuk akal adalah memiliki tidak lebih dari satu anggota per antarmuka.
DIP dapat menyebabkan kode tidak dapat digunakan. Saya telah melihat kelas dengan sejumlah besar parameter dalam nama DIP. Kelas-kelas ini biasanya akan "baru" di bagian komposit mereka, tetapi saya nama-kemampuan uji kita tidak boleh menggunakan kata kunci baru lagi.
SOLID sendiri tidak cukup bagi Anda untuk menulis kode bersih. Saya telah melihat buku Robert C. Martin, " Clean Code: A Handbook of Agile Software Craftsmanship ". Masalah terbesar dengannya adalah mudahnya membaca buku ini dan menafsirkannya sebagai aturan. Jika Anda melakukannya, Anda tidak mengerti intinya. Ini berisi daftar besar aroma, heuristik dan prinsip - lebih dari sekadar lima dari SOLID. Semua 'prinsip' ini tidak benar-benar prinsip tetapi pedoman. Paman Bob mendeskripsikannya sendiri sebagai "lubang kecil" untuk konsep. Mereka adalah tindakan penyeimbang; mengikuti pedoman apa pun secara membabi buta akan menyebabkan masalah.
sumber
Inilah pendapat saya:
Meskipun prinsip-prinsip SOLID bertujuan untuk basis kode yang tidak berlebihan dan fleksibel, ini mungkin merupakan trade-off dalam keterbacaan dan pemeliharaan jika ada terlalu banyak kelas dan lapisan.
Ini terutama tentang jumlah abstraksi . Sejumlah besar kelas mungkin ok jika didasarkan pada beberapa abstraksi. Karena kami tidak tahu ukuran dan spesifik proyek Anda, sulit untuk mengatakannya, tetapi sedikit mengkhawatirkan bahwa Anda menyebutkan beberapa layer selain sejumlah besar kelas.
Saya kira prinsip-prinsip SOLID tidak tidak setuju dengan OOP, tetapi masih mungkin untuk menulis kode yang tidak bersih mengikuti mereka.
sumber
Pada hari-hari awal saya berkembang, saya mulai menulis Roguelike di C ++. Karena saya ingin menerapkan metodologi berorientasi objek yang baik yang saya pelajari dari pendidikan saya, saya langsung melihat item permainan sebagai objek C ++.
Potion
,Swords
,Food
,Axe
,Javelins
Dll semua berasal dari inti dasarItem
kode, penanganan nama, ikon, berat badan, hal semacam itu.Kemudian, saya membuat kode logika tas, dan menghadapi masalah. Saya dapat memasukkannya ke
Items
dalam tas, tetapi kemudian, jika saya memilih satu, bagaimana saya tahu apakah itu aPotion
atau aSword
? Saya mencari di Internet bagaimana cara menurunkan barang. Saya meretas opsi kompiler untuk mengaktifkan informasi runtime sehingga saya akan tahu apaItem
tipe sebenarnya saya yang abstrak , dan mulai beralih logika pada jenis untuk mengetahui operasi apa yang akan saya izinkan (misalnya menghindari minumSwords
dan memakaiPotions
kakiku)Itu pada dasarnya mengubah kode dalam bola besar lumpur setengah copypasted. Seiring berjalannya proyek, saya mulai mengerti apa itu kegagalan desain. Apa yang terjadi adalah saya mencoba menggunakan kelas untuk merepresentasikan nilai. Hirarki kelas saya bukanlah abstraksi yang bermakna. Apa yang saya harus lakukan adalah membuat
Item
menerapkan satu set fungsi, sepertiEquip ()
,Apply ()
, danThrow ()
, dan membuat setiap berperilaku berdasarkan nilai-nilai. Menggunakan enum untuk mewakili slot peralatan. Menggunakan enum untuk mewakili jenis senjata yang berbeda. Menggunakan lebih banyak nilai dan lebih sedikit pengelompokan, karena subklasifikasi saya tidak memiliki tujuan lain selain untuk mengisi nilai akhir ini.Karena Anda menghadapi multiplikasi objek di bawah lapisan abstraksi, saya pikir wawasan saya dapat berharga di sini. Jika Anda tampaknya memiliki terlalu banyak jenis objek, mungkin Anda bingung jenis apa yang seharusnya dengan apa yang seharusnya menjadi nilai.
sumber
Saya benar-benar di pihak teman Anda, tetapi bisa jadi masalah domain kami dan jenis masalah dan desain yang kami tangani dan terutama jenis hal apa yang mungkin membutuhkan perubahan di masa depan. Masalah berbeda, solusi berbeda. Saya tidak percaya benar atau salah, hanya programmer yang berusaha menemukan cara terbaik yang mereka bisa untuk memecahkan masalah desain khusus mereka. Saya bekerja di VFX yang tidak terlalu berbeda dengan mesin game.
Tetapi masalah bagi saya bahwa saya berjuang dengan apa yang paling tidak bisa disebut sedikit lebih dari arsitektur SOLID-conforming (itu berbasis COM), mungkin secara kasar dididihkan ke "terlalu banyak kelas" atau "terlalu banyak fungsi" sebagai teman Anda mungkin menjelaskan. Saya akan secara khusus mengatakan, "terlalu banyak interaksi, terlalu banyak tempat yang mungkin dapat berperilaku tidak pantas, terlalu banyak tempat yang dapat menyebabkan efek samping, terlalu banyak tempat yang mungkin perlu diubah, dan terlalu banyak tempat yang mungkin tidak melakukan apa yang kami pikir mereka lakukan . "
Kami memiliki beberapa antarmuka abstrak (dan murni) yang diimplementasikan oleh sejumlah subtipe, seperti itu (membuat diagram ini dalam konteks berbicara tentang manfaat ECS, mengabaikan komentar kiri bawah):
Di mana antarmuka gerak atau antarmuka node adegan dapat diimplementasikan oleh ratusan subtipe: lampu, kamera, jerat, pemecah fisika, shader, tekstur, tulang, bentuk primitif, kurva, dll. (Dan sering ada beberapa jenis masing-masing ). Dan masalah utamanya adalah desain itu tidak begitu stabil. Kami memiliki persyaratan yang berubah dan terkadang antarmuka sendiri harus berubah, dan ketika Anda ingin mengubah antarmuka abstrak yang diterapkan oleh 200 subtipe, itu adalah perubahan yang sangat mahal. Kami mulai mengurangi hal itu dengan menggunakan kelas dasar abstrak di antaranya mengurangi biaya perubahan desain seperti itu, tetapi mereka masih mahal.
Jadi sebagai alternatif saya mulai menjelajahi arsitektur sistem entitas-komponen yang digunakan agak umum di industri game. Itu mengubah segalanya menjadi seperti ini:
Dan wow! Itu adalah perbedaan dalam hal rawatan. Ketergantungan tidak lagi mengalir menuju abstraksi , tetapi menuju data (komponen). Dan setidaknya dalam kasus saya, data jauh lebih stabil dan lebih mudah untuk mendapatkan yang benar dalam hal desain dimuka terlepas dari perubahan persyaratan (meskipun apa yang bisa kita lakukan dengan data yang sama terus berubah dengan perubahan persyaratan).
Juga karena entitas dalam ECS menggunakan komposisi alih-alih pewarisan, mereka sebenarnya tidak perlu mengandung fungsionalitas. Mereka hanyalah "wadah komponen" analog. Itu membuatnya begitu 200 subtipe analog yang mengimplementasikan antarmuka gerak berubah menjadi 200 entitas contoh (bukan tipe terpisah dengan kode terpisah) yang hanya menyimpan komponen gerakan (yang tidak lain adalah data yang terkait dengan gerakan). A
PointLight
tidak lagi menjadi kelas / subtipe yang terpisah. Ini bukan kelas sama sekali. Ini adalah instance dari entitas yang hanya menggabungkan beberapa komponen (data) yang terkait dengan keberadaannya di ruang (gerak) dan sifat spesifik lampu titik. Satu-satunya fungsi yang terkait dengannya adalah di dalam sistem, sepertiRenderSystem
, yang mencari komponen cahaya dalam adegan untuk menentukan cara membuat adegan.Dengan perubahan persyaratan di bawah pendekatan ECS, sering kali hanya ada kebutuhan untuk mengubah satu atau dua sistem yang beroperasi pada data itu atau hanya memperkenalkan sistem baru di samping, atau memperkenalkan komponen baru jika data baru diperlukan.
Jadi untuk domain saya setidaknya, dan saya hampir yakin itu bukan untuk semua orang, ini membuat segalanya jauh lebih mudah karena ketergantungan mengalir menuju stabilitas (hal-hal yang tidak perlu sering berubah sama sekali). Itu tidak terjadi dalam arsitektur COM ketika dependensi secara seragam mengalir menuju abstraksi. Dalam kasus saya, jauh lebih mudah untuk mencari tahu data apa yang diperlukan untuk gerak di muka daripada semua hal yang mungkin Anda lakukan dengannya, yang sering berubah sedikit selama berbulan-bulan atau bertahun-tahun ketika persyaratan baru datang.
Yah, kode bersih saya tidak bisa mengatakan karena beberapa orang menyamakan kode bersih dengan SOLID, tapi pasti ada beberapa kasus di mana memisahkan data dari fungsi seperti ECS, dan mengarahkan kembali ketergantungan menjauh dari abstraksi terhadap data pasti dapat membuat banyak hal lebih mudah untuk dilakukan. berubah, untuk alasan penggandengan yang jelas, jika data akan jauh lebih stabil daripada abstraksi. Tentu saja ketergantungan pada data dapat membuat pemeliharaan invarian menjadi sulit, tetapi ECS cenderung memitigasi hal tersebut seminimal mungkin dengan sistem organisasi yang meminimalkan jumlah sistem yang mengakses setiap jenis komponen tertentu.
Itu tidak selalu bahwa dependensi harus mengalir ke abstraksi seperti DIP akan menyarankan; ketergantungan harus mengalir ke hal-hal yang sangat tidak mungkin membutuhkan perubahan di masa depan. Itu mungkin atau mungkin bukan abstraksi dalam semua kasus (jelas bukan milik saya).
Saya tidak yakin apakah ECS benar-benar citarasa OOP. Beberapa orang mendefinisikannya seperti itu, tetapi saya melihatnya sangat berbeda secara inheren dengan karakteristik kopling dan pemisahan data (komponen) dari fungsionalitas (sistem) dan kurangnya enkapsulasi data. Jika itu dianggap sebagai bentuk OOP, saya akan berpikir itu sangat bertentangan dengan SOLID (setidaknya ide-ide ketat SRP, buka / tutup, substitusi liskov, dan DIP). Tapi saya harap ini adalah contoh yang masuk akal dari satu kasus dan domain di mana aspek paling mendasar dari SOLID, setidaknya karena orang umumnya akan menafsirkannya dalam konteks OOP yang lebih dikenal, mungkin tidak begitu berlaku.
Kelas kecil
ECS telah banyak menantang dan mengubah pandangan saya. Seperti Anda, saya dulu berpikir bahwa gagasan tentang pemeliharaan adalah memiliki implementasi paling sederhana untuk hal-hal yang mungkin, yang menyiratkan banyak hal, dan lebih jauh lagi, banyak hal yang saling tergantung (bahkan jika saling ketergantungan adalah di antara abstraksi). Sangat masuk akal jika Anda memperbesar hanya pada satu kelas atau fungsi untuk ingin melihat implementasi yang paling mudah, sederhana, dan jika kita tidak melihatnya, refactor dan bahkan mungkin membusuk lebih lanjut. Tetapi akibatnya mudah untuk melewatkan apa yang terjadi dengan dunia luar, karena setiap kali Anda membagi sesuatu yang relatif kompleks menjadi 2 hal atau lebih, 2 hal atau lebih itu pasti berinteraksi * (lihat di bawah) satu sama lain di beberapa cara, atau sesuatu di luar harus berinteraksi dengan mereka semua.
Saat ini saya menemukan ada tindakan penyeimbangan antara kesederhanaan sesuatu dan berapa banyak hal yang ada dan berapa banyak interaksi yang diperlukan. Sistem dalam ECS cenderung lumayan dengan implementasi non-sepele untuk beroperasi pada data, seperti
PhysicsSystem
atauRenderSystem
atauGuiLayoutSystem
. Namun, fakta bahwa produk yang kompleks membutuhkan begitu sedikit dari mereka cenderung membuatnya mudah untuk melangkah mundur dan alasan tentang perilaku keseluruhan basis kode seluruh. Ada sesuatu di sana yang mungkin menyarankan bahwa mungkin bukan ide yang buruk untuk bersandar pada sisi yang lebih sedikit, kelas bulkier (masih melakukan tanggung jawab tunggal yang bisa dibilang), jika itu berarti lebih sedikit kelas untuk dipertahankan dan dipikirkan, dan lebih sedikit interaksi di seluruh sistem.Interaksi
Saya mengatakan "interaksi" daripada "penggandengan" (meskipun mengurangi interaksi berarti mengurangi keduanya), karena Anda dapat menggunakan abstraksi untuk memisahkan dua objek konkret, tetapi keduanya masih saling berbicara. Mereka masih bisa menimbulkan efek samping dalam proses komunikasi tidak langsung ini. Dan seringkali saya menemukan kemampuan saya untuk beralasan tentang kebenaran sistem terkait dengan "interaksi" ini lebih dari "penggandengan". Meminimalkan interaksi cenderung membuat banyak hal lebih mudah bagi saya untuk mempertimbangkan segala sesuatu dari pandangan mata burung. Itu berarti hal-hal yang tidak saling berbicara sama sekali, dan dari pengertian itu, ECS juga cenderung untuk benar-benar meminimalkan "interaksi", dan bukan hanya penggabungan, ke tingkat minimum minimum (setidaknya saya berlindung '
Yang mengatakan, ini mungkin setidaknya sebagian dan kelemahan pribadi saya. Saya telah menemukan hambatan terbesar bagi saya untuk menciptakan sistem skala besar, dan masih yakin alasan tentang mereka, menavigasi melalui mereka, dan merasa seperti saya dapat membuat perubahan potensial yang diinginkan di mana saja dengan cara yang dapat diprediksi, adalah manajemen negara dan sumber daya bersama dengan efek samping. Ini adalah kendala terbesar yang mulai muncul ketika saya beralih dari puluhan ribu LOC menjadi ratusan ribu LOC menjadi jutaan LOC, bahkan untuk kode yang saya tulis sendiri sepenuhnya. Jika ada sesuatu yang memperlambat saya untuk merangkak di atas segalanya, ini pengertian bahwa saya tidak bisa lagi memahami apa yang terjadi dalam hal status aplikasi, data, efek samping. Saya t' Bukan waktu robot yang diperlukan untuk membuat perubahan yang memperlambat saya, sama halnya dengan ketidakmampuan untuk memahami dampak penuh dari perubahan jika sistem tumbuh di luar kemampuan pikiran saya untuk memikirkannya. Dan mengurangi interaksi telah, bagi saya, cara paling efektif untuk memungkinkan produk tumbuh lebih besar dengan lebih banyak fitur tanpa saya secara pribadi kewalahan oleh hal-hal ini, karena mengurangi interaksi seminimal mungkin juga mengurangi jumlah tempat yang dapat bahkan mungkin mengubah status aplikasi dan menyebabkan efek samping secara substansial.
Itu dapat mengubah sesuatu seperti ini (di mana segala sesuatu dalam diagram memiliki fungsionalitas, dan jelas skenario dunia nyata akan memiliki banyak, berkali-kali jumlah objek, dan ini adalah diagram "interaksi", bukan kopling, sebagai kopling seseorang akan memiliki abstraksi di antaranya):
... untuk ini di mana hanya sistem yang memiliki fungsionalitas (komponen biru sekarang hanya data, dan sekarang ini adalah diagram kopling):
Dan ada pemikiran yang muncul tentang semua ini dan mungkin cara untuk membingkai beberapa manfaat ini dalam konteks OOP yang lebih sesuai yang lebih kompatibel dengan SOLID, tapi saya belum menemukan desain dan kata-kata dulu, dan saya menemukannya sulit karena terminologi saya terbiasa membuang semua yang berhubungan langsung dengan OOP. Saya terus berusaha mencari tahu membaca jawaban orang-orang di sini dan juga mencoba yang terbaik untuk merumuskan jawaban saya, tetapi ada beberapa hal yang sangat menarik tentang sifat ECS yang saya belum dapat dengan sempurna menempatkan jari saya pada itu mungkin dapat diterapkan secara lebih luas bahkan untuk arsitektur yang tidak menggunakannya. Saya juga berharap jawaban ini tidak muncul sebagai promosi ECS! Saya hanya merasa sangat menarik karena merancang ECS telah benar-benar mengubah pikiran saya secara drastis,
sumber
Prinsip-prinsip SOLID baik, tetapi KISS dan YAGNI mengambil prioritas jika terjadi konflik. Tujuan SOLID adalah mengelola kompleksitas, tetapi jika menerapkan SOLID itu sendiri membuat kode lebih kompleks maka ia mengalahkan tujuannya. Sebagai contoh, jika Anda memiliki program kecil dengan hanya beberapa kelas, menerapkan DI, pemisahan antarmuka, dll. Mungkin akan sangat meningkatkan kompleksitas keseluruhan program.
Prinsip terbuka / tertutup sangat kontroversial. Pada dasarnya ia mengatakan Anda harus menambahkan fitur ke kelas dengan membuat subclass atau implementasi terpisah dari antarmuka yang sama, tetapi membiarkan kelas asli tidak tersentuh. Jika Anda mengelola perpustakaan atau layanan yang digunakan oleh klien yang tidak terkoordinasi, ini masuk akal, karena Anda tidak ingin menghentikan perilaku yang bergantung pada klien yang keluar. Namun jika Anda memodifikasi kelas yang hanya digunakan di aplikasi Anda sendiri, seringkali akan jauh lebih sederhana dan bersih untuk hanya memodifikasi kelas.
sumber
Dalam pengalaman saya: -
Kelas besar secara eksponensial lebih sulit dipertahankan karena kelasnya semakin besar.
Kelas kecil lebih mudah dipelihara dan kesulitan mempertahankan koleksi kelas kecil meningkat secara aritmatik ke jumlah kelas.
Terkadang kelas besar tidak bisa dihindari masalah besar terkadang membutuhkan kelas besar, tetapi, mereka jauh lebih sulit untuk dibaca dan dipahami. Untuk kelas kecil yang lebih baik namanya, nama saja sudah cukup untuk pemahaman Anda bahkan tidak perlu melihat kode kecuali ada masalah yang sangat spesifik dengan kelas tersebut.
sumber
Saya selalu merasa sulit untuk menarik garis antara 'S' solid dan (mungkin kuno) perlu membiarkan suatu objek memiliki semua pengetahuan tentang dirinya sendiri.
15 tahun yang lalu saya bekerja dengan pengembang Deplhi yang memiliki cawan suci mereka untuk memiliki kelas yang berisi segalanya. Jadi untuk hipotek Anda dapat menambahkan asuransi dan pembayaran serta pendapatan dan pinjaman serta info pajak dan Anda dapat menghitung pajak yang harus dibayar, pajak yang harus dikurangi dan dapat membuat serial sendiri, bertahan sendiri di disk, dll.
Dan sekarang saya memiliki objek yang sama yang terbagi dalam banyak kelas yang lebih kecil yang memiliki keuntungan bahwa mereka dapat diuji unit lebih mudah dan lebih baik tetapi tidak memberikan gambaran yang baik dari seluruh model bisnis.
Dan ya saya tahu Anda tidak ingin mengikat objek Anda ke database tetapi Anda bisa menyuntikkan repositori di kelas hipotek besar untuk menyelesaikannya.
Selain itu tidak selalu mudah untuk menemukan nama yang bagus untuk kelas yang hanya melakukan hal kecil.
Jadi saya tidak yakin tentang 'S' selalu merupakan ide yang bagus.
sumber