Menurut dokumentasi Microsoft, artikel prinsip Wikipedia SOLID, atau sebagian besar arsitek TI kita harus memastikan bahwa setiap kelas hanya memiliki satu tanggung jawab. Saya ingin tahu mengapa, karena jika semua orang tampaknya setuju dengan aturan ini, tidak ada yang tampaknya setuju tentang alasan aturan ini.
Beberapa mengutip pemeliharaan yang lebih baik, beberapa mengatakan itu memberikan pengujian yang mudah atau membuat kelas lebih kuat, atau keamanan. Apa yang benar dan apa arti sebenarnya? Mengapa ini membuat pemeliharaan lebih baik, pengujian lebih mudah atau kode lebih kuat?
design-patterns
architecture
solid
single-responsibility
Bastien Vandamme
sumber
sumber
Jawaban:
Modularitas. Bahasa apa pun yang layak akan memberi Anda cara untuk menyatukan potongan-potongan kode, tetapi tidak ada cara umum untuk menghapus kode yang besar tanpa programmer melakukan operasi pada sumbernya. Dengan memasukkan banyak tugas ke dalam satu konstruksi kode, Anda merampok diri sendiri dan orang lain dari kesempatan untuk menggabungkan bagian-bagiannya dengan cara lain, dan memperkenalkan dependensi yang tidak perlu yang dapat menyebabkan perubahan pada satu bagian mempengaruhi yang lain.
SRP sama berlaku untuk fungsi seperti halnya untuk kelas, tetapi bahasa OOP arus utama relatif buruk dalam menempelkan fungsi bersama.
sumber
Perawatan yang lebih baik, pengujian yang mudah, perbaikan bug yang lebih cepat hanyalah hasil penerapan SRP yang sangat menyenangkan. Alasan utama (sebagaimana dikatakan Robert C. Matin) adalah:
Dengan kata lain, SRP memunculkan perubahan lokalitas .
SRP juga mempromosikan kode KERING. Selama kita memiliki kelas yang hanya memiliki satu tanggung jawab, kita dapat memilih untuk menggunakannya di mana pun kita inginkan. Jika kita memiliki kelas yang memiliki dua tanggung jawab, tetapi kita hanya perlu satu dari mereka dan yang kedua mengganggu, kita memiliki 2 pilihan:
sumber
Mudah membuat kode untuk memperbaiki masalah tertentu. Lebih rumit untuk membuat kode yang memperbaiki masalah itu sambil memungkinkan perubahan selanjutnya dilakukan dengan aman. SOLID menyediakan serangkaian praktik yang membuat kode lebih baik.
Yang mana yang benar: Mereka bertiga. Semua itu adalah manfaat menggunakan tanggung jawab tunggal dan alasan Anda harus menggunakannya.
Apa artinya:
Cobalah membuat kode untuk beberapa saat mengikuti prinsip, dan kunjungi kembali kode itu nanti untuk melakukan beberapa perubahan. Anda akan melihat keuntungan besar yang diberikannya.
Anda melakukan hal yang sama untuk setiap kelas, dan berakhir dengan lebih banyak kelas, semua sesuai dengan SRP. Itu membuat struktur lebih kompleks dari sudut pandang koneksi, tetapi kesederhanaan setiap kelas membenarkannya.
sumber
Berikut adalah argumen yang, dalam pandangan saya, mendukung klaim bahwa Prinsip Tanggung Jawab Tunggal adalah praktik yang baik. Saya juga menyediakan tautan ke literatur lebih lanjut, di mana Anda dapat membaca alasan yang lebih rinci - dan lebih fasih daripada milik saya:
Pemeliharaan yang lebih baik : idealnya, setiap kali fungsi sistem harus berubah, akan ada satu dan hanya satu kelas yang harus diubah. Pemetaan yang jelas antara kelas dan tanggung jawab berarti bahwa setiap pengembang yang terlibat dalam proyek dapat mengidentifikasi kelas ini. (Seperti yang dicatat oleh @ MaciejChałapuk, lihat Robert C. Martin, "Kode Bersih" .)
Pengujian yang lebih mudah : idealnya, kelas-kelas harus memiliki antarmuka publik seminimal mungkin, dan pengujian harus hanya membahas antarmuka publik ini. Jika Anda tidak dapat menguji dengan jelas, karena banyak bagian dari kelas Anda bersifat pribadi, maka ini adalah tanda yang jelas bahwa kelas Anda memiliki terlalu banyak tanggung jawab, dan bahwa Anda harus membaginya dalam subclass yang lebih kecil. Harap perhatikan bahwa ini berlaku juga untuk bahasa-bahasa di mana tidak ada anggota kelas 'publik' atau 'pribadi'; memiliki antarmuka publik yang kecil berarti sangat jelas untuk kode klien bagian mana dari kelas yang seharusnya digunakan. (Lihat Kent Beck, "Pengembangan Test-Driven" untuk lebih jelasnya.)
Robust code : kode Anda tidak akan gagal lebih atau kurang sering karena ditulis dengan baik; tetapi, seperti semua kode, tujuan utamanya bukan untuk berkomunikasi dengan mesin , tetapi dengan sesama pengembang (lihat Kent Beck, "Pola Implementasi" , Bab 1.) Basis kode yang jelas lebih mudah untuk dipikirkan, sehingga lebih sedikit bug akan diperkenalkan , dan lebih sedikit waktu akan berlalu antara menemukan bug dan memperbaikinya.
sumber
Ada beberapa alasan, tetapi yang saya suka adalah pendekatan yang digunakan oleh banyak program UNIX awal: Lakukan satu hal dengan baik. Cukup sulit untuk melakukannya dengan satu hal, dan semakin sulit semakin banyak hal yang Anda coba lakukan.
Alasan lain adalah membatasi dan mengendalikan efek samping. Saya menyukai pembuka pintu pembuat kopi kombinasi saya. Sayangnya, kopi biasanya meluap ketika ada tamu. Saya lupa menutup pintu setelah saya membuat kopi beberapa hari yang lalu dan seseorang mencurinya.
Dari sudut pandang psikologis, Anda hanya dapat melacak beberapa hal sekaligus. Estimasi umum adalah tujuh plus atau minus dua. Jika suatu kelas melakukan banyak hal, Anda perlu melacak semuanya sekaligus. Ini mengurangi kemampuan Anda untuk melacak apa yang Anda lakukan. Jika suatu kelas melakukan tiga hal, dan Anda hanya menginginkan satu di antaranya, Anda dapat menggunakan kemampuan Anda untuk melacak hal-hal sebelum Anda benar-benar melakukan sesuatu dengan kelas tersebut.
Melakukan banyak hal meningkatkan kompleksitas kode. Di luar kode yang paling sederhana, meningkatkan kompleksitas meningkatkan kemungkinan bug. Dari sudut pandang ini Anda ingin kelas sesederhana mungkin.
Menguji kelas yang melakukan satu hal jauh lebih sederhana. Anda tidak perlu memverifikasi bahwa hal kedua yang dilakukan atau tidak terjadi di kelas untuk setiap tes. Anda juga tidak perlu memperbaiki kondisi yang rusak dan menguji ulang ketika salah satu dari tes ini gagal.
sumber
Karena perangkat lunak adalah organik. Persyaratan berubah terus-menerus sehingga Anda harus memanipulasi komponen dengan sesedikit mungkin sakit kepala. Dengan tidak mengikuti prinsip-prinsip SOLID, Anda mungkin berakhir dengan basis kode yang ditetapkan dalam beton.
Bayangkan sebuah rumah dengan dinding beton bertulang. Apa yang terjadi ketika Anda mengeluarkan tembok ini tanpa dukungan apa pun? Rumah itu mungkin akan runtuh. Dalam perangkat lunak, kami tidak menginginkan ini, jadi kami menyusun aplikasi sedemikian rupa sehingga Anda dapat dengan mudah memindahkan / mengganti / memodifikasi komponen tanpa menyebabkan banyak kerusakan.
sumber
Saya mengikuti pikiran:
1 Class = 1 Job
.Menggunakan Analogi Fisiologi: Motor (Sistem Saraf), Respirasi (Paru-paru), Pencernaan (Perut), Penciuman (Pengamatan), dll. Masing-masing akan memiliki subset pengontrol, tetapi masing-masing hanya memiliki 1 tanggung jawab, apakah itu untuk mengelola cara masing-masing subsistem mereka bekerja atau apakah mereka merupakan subsistem titik akhir dan hanya melakukan 1 tugas, seperti mengangkat jari atau menumbuhkan folikel rambut.
Jangan bingung fakta bahwa itu mungkin bertindak sebagai manajer, bukan pekerja. Beberapa pekerja akhirnya dipromosikan menjadi Manajer, ketika pekerjaan yang mereka lakukan menjadi terlalu rumit untuk satu proses untuk ditangani sendiri.
Bagian paling rumit dari apa yang saya alami, adalah mengetahui kapan harus menetapkan Kelas sebagai proses Operator, Supervisor, atau Manajer. Apa pun yang terjadi, Anda harus memperhatikan dan menunjukkan fungsinya untuk 1 tanggung jawab (Operator, Supervisor, atau Manajer).
Ketika Kelas / Objek melakukan lebih dari 1 peran tipe ini, Anda akan menemukan bahwa proses keseluruhan akan mulai mengalami masalah kinerja, atau memproses leher botol.
sumber
Lung
kelas, saya berpendapat bahwa instancePerson
harus tetapBreathe
, dan karenanyaPerson
kelas harus mengandung cukup logika untuk, setidaknya, mendelegasikan tanggung jawab yang terkait dengan metode itu. Saya lebih lanjut menyarankan bahwa hutan entitas yang saling berhubungan yang hanya dapat diakses melalui pemilik bersama seringkali lebih mudah untuk dipertimbangkan daripada hutan yang memiliki beberapa titik akses independen.Person
kelas memiliki tugasnya sebagai delegasi dari semua fungsi yang terkait dengan entitas "nyata-dunia-manusia-manusia" yang sangat rumit, termasuk asosiasi berbagai bagiannya . Mempunyai entitas melakukan 500 hal itu jelek, tetapi jika itu cara sistem dunia nyata dimodelkan bekerja, memiliki kelas yang mendelegasikan 500 fungsi sambil mempertahankan satu identitas mungkin lebih baik daripada harus melakukan segala sesuatu dengan potongan terpisah.Person
tetapi masih melaporkan rantai pada keberhasilan / kegagalan tetapi tidak selalu mempengaruhi yang lain. 500 Fungsi (walaupun ditetapkan sebagai contoh, akan menjadi berlebihan dan tidak didukung) saya mencoba untuk menjaga tipe fungsionalitas yang diturunkan dan modular.Fred.vision.lookAt(George)
masuk akal, tetapi mengizinkan kode untuk mengatakansomeEyes = Fred.vision; someTubes = Fred.digestion
tampak menjengkelkan karena mengaburkan hubungan antarasomeEyes
dansomeTubes
.Terutama dengan prinsip penting seperti Tanggung Jawab Tunggal, saya pribadi berharap bahwa ada banyak alasan mengapa orang mengadopsi prinsip ini.
Beberapa alasan itu mungkin:
Perhatikan juga bahwa SRP hadir dengan bundel prinsip SOLID. Mematuhi SRP dan mengabaikan sisanya sama buruknya dengan tidak melakukan SRP sejak awal. Jadi Anda tidak harus mengevaluasi SRP dengan sendirinya, tetapi dalam konteks semua prinsip SOLID.
sumber
... test is not affected by other responsibilities the class has
, bisakah Anda menjelaskan hal ini?Cara terbaik untuk memahami pentingnya prinsip-prinsip ini adalah memiliki kebutuhan.
Ketika saya masih seorang programmer pemula, saya tidak terlalu memikirkan desain, bahkan saya tidak tahu ada pola desain. Ketika program saya berkembang, mengubah satu hal berarti mengubah banyak hal lainnya. Sulit untuk melacak bug, kodenya besar dan berulang. Tidak ada banyak hierarki objek, semuanya ada di mana-mana. Menambahkan sesuatu yang baru, atau menghapus sesuatu yang lama akan memunculkan kesalahan di bagian lain dari program. Sosok pergi.
Pada proyek-proyek kecil, itu mungkin tidak masalah, tetapi dalam proyek-proyek besar, hal-hal bisa sangat mengerikan. Kemudian ketika saya menemukan konsep desain patters, saya berkata pada diri sendiri, "oh yah, melakukan ini akan membuat segalanya jadi lebih mudah kalau begitu".
Anda benar-benar tidak dapat memahami pentingnya pola desain sampai kebutuhan muncul. Saya menghormati polanya karena dari pengalaman saya bisa mengatakan mereka membuat pemeliharaan kode mudah dan kode kuat.
Namun, sama seperti Anda, saya masih ragu tentang "pengujian mudah", karena saya belum memiliki kebutuhan untuk masuk ke unit testing.
sumber
Jawabannya adalah, seperti yang orang lain tunjukkan, semuanya benar, dan mereka semua saling memasukkan satu sama lain, lebih mudah untuk diuji membuat pemeliharaan lebih mudah membuat kode lebih kuat membuat pemeliharaan lebih mudah dan sebagainya ...
Semua ini bermuara pada prinsip utama - kode harus sekecil dan melakukan sesedikit yang diperlukan untuk menyelesaikan pekerjaan. Ini berlaku untuk aplikasi, file, atau kelas sebanyak fungsi. Semakin banyak hal yang dilakukan oleh sepotong kode, semakin sulit untuk memahami, mempertahankan, memperluas, atau menguji.
Saya pikir itu bisa diringkas dalam satu kata: ruang lingkup. Perhatikan ruang lingkup artefak, semakin sedikit hal dalam ruang lingkup pada titik tertentu dalam suatu aplikasi, semakin baik.
Lingkup diperluas = lebih banyak kerumitan = lebih banyak cara untuk kesalahan terjadi.
sumber
Jika kelas terlalu besar, akan sulit untuk mempertahankan, menguji dan memahami, jawaban lain telah mencakup kehendak ini.
Dimungkinkan bagi suatu kelas untuk memiliki lebih dari satu tanggung jawab tanpa masalah, tetapi Anda segera mendapatkan masalah dengan kelas yang terlalu rumit.
Namun memiliki aturan sederhana "hanya satu tanggung jawab" hanya membuatnya lebih mudah untuk mengetahui kapan Anda membutuhkan kelas baru .
Namun mendefinisikan "tanggung jawab" itu sulit, itu tidak berarti "melakukan segala sesuatu yang menurut spesifikasi aplikasi", keterampilan sebenarnya adalah tahu bagaimana memecah masalah menjadi unit-unit kecil "tanggung jawab".
sumber