Prinsip Tanggungjawab Tunggal di Jawa

1. Gambaran keseluruhan

Dalam tutorial ini, kita akan membincangkan Prinsip Tanggungjawab Tunggal, sebagai salah satu prinsip SOLID pengaturcaraan berorientasikan objek.

Secara keseluruhan, kami akan membahas secara mendalam apa prinsip ini dan bagaimana menerapkannya semasa merancang perisian kami. Selanjutnya, kami akan menerangkan bila prinsip ini boleh mengelirukan.

* SRP = Prinsip Tanggungjawab Tunggal

2. Prinsip Tanggungjawab Tunggal

Seperti namanya, prinsip ini menyatakan bahawa setiap kelas harus mempunyai satu tanggungjawab, satu tujuan tunggal . Ini bermaksud bahawa satu kelas hanya akan melakukan satu pekerjaan, yang menyebabkan kita membuat kesimpulan bahawa ia hanya boleh mempunyai satu sebab untuk berubah .

Kami tidak mahu objek yang terlalu banyak tahu dan mempunyai tingkah laku yang tidak berkaitan. Kelas-kelas ini lebih sukar untuk dikekalkan. Sebagai contoh, jika kita mempunyai kelas yang banyak kita ubah, dan kerana alasan yang berbeza, maka kelas ini harus dipecah menjadi lebih banyak kelas, masing-masing menangani satu masalah. Pasti, jika berlaku ralat, akan lebih mudah dicari.

Mari kita pertimbangkan kelas yang mengandungi kod yang mengubah teks dalam beberapa cara. Satu-satunya tugas kelas ini ialah memanipulasi teks .

public class TextManipulator { private String text; public TextManipulator(String text) { this.text = text; } public String getText() { return text; } public void appendText(String newText) { text = text.concat(newText); } public String findWordAndReplace(String word, String replacementWord) { if (text.contains(word)) { text = text.replace(word, replacementWord); } return text; } public String findWordAndDelete(String word) { if (text.contains(word)) { text = text.replace(word, ""); } return text; } public void printText() { System.out.println(textManipulator.getText()); } }

Walaupun ini kelihatan baik, ini bukan contoh SRP yang baik. Di sini kita mempunyai dua tanggungjawab : memanipulasi dan mencetak teks .

Mempunyai kaedah mencetak teks dalam kelas ini melanggar Prinsip Tanggungjawab Tunggal. Untuk tujuan ini, kita harus membuat kelas lain, yang hanya akan menangani percetakan teks:

public class TextPrinter { TextManipulator textManipulator; public TextPrinter(TextManipulator textManipulator) { this.textManipulator = textManipulator; } public void printText() { System.out.println(textManipulator.getText()); } public void printOutEachWordOfText() { System.out.println(Arrays.toString(textManipulator.getText().split(" "))); } public void printRangeOfCharacters(int startingIndex, int endIndex) { System.out.println(textManipulator.getText().substring(startingIndex, endIndex)); } }

Sekarang, di kelas ini, kita dapat membuat kaedah untuk seberapa banyak variasi mencetak teks yang kita mahukan, kerana itulah tugasnya.

3. Bagaimana Prinsip Ini Boleh Menyesatkan?

Caranya melaksanakan SRP dalam perisian kami adalah mengetahui tanggungjawab setiap kelas.

Walau bagaimanapun, setiap pembangun mempunyai visi mereka mengenai tujuan kelas , yang menjadikan semuanya sukar. Oleh kerana kita tidak mempunyai arahan yang tegas tentang bagaimana melaksanakan prinsip ini, kita ditinggalkan dengan tafsiran kita tentang tanggungjawab yang akan dilakukan.

Ini bermaksud bahawa kadang-kadang hanya kita, sebagai pereka aplikasi kita, yang dapat memutuskan apakah ada sesuatu yang berada dalam ruang lingkup kelas atau tidak.

Semasa menulis kelas mengikut prinsip SRP, kita harus memikirkan domain masalah, keperluan perniagaan, dan seni bina aplikasi. Ini sangat subjektif, yang menjadikan pelaksanaan prinsip ini lebih sukar daripada yang sepertinya. Ini tidak semudah contoh yang kita ada dalam tutorial ini.

Ini membawa kita ke titik seterusnya.

4. Perpaduan

Mengikut prinsip SRP, kelas kami akan mematuhi satu fungsi. Kaedah dan data mereka akan berkaitan dengan satu tujuan yang jelas. Ini bermaksud kohesi yang tinggi, serta ketahanan, yang bersama-sama mengurangkan kesilapan .

Semasa merancang perisian berdasarkan prinsip SRP, kesatuan adalah mustahak, kerana ia dapat membantu kita mencari tanggungjawab tunggal untuk kelas kita. Konsep ini juga membantu kita mencari kelas yang mempunyai lebih daripada satu tanggungjawab.

Mari kembali ke kaedah kelas TextManipulator kami :

... public void appendText(String newText) { text = text.concat(newText); } public String findWordAndReplace(String word, String replacementWord) { if (text.contains(word)) { text = text.replace(word, replacementWord); } return text; } public String findWordAndDelete(String word) { if (text.contains(word)) { text = text.replace(word, ""); } return text; } ...

Di sini, kami mempunyai gambaran yang jelas mengenai apa yang dilakukan oleh kelas ini: Manipulasi teks.

Tetapi, jika kita tidak memikirkan kohesi dan kita tidak mempunyai definisi yang jelas tentang tanggungjawab kelas ini, kita boleh mengatakan bahawa menulis dan mengemas kini teks adalah dua pekerjaan yang berbeza dan terpisah. Memimpin oleh pemikiran ini, kita dapat menyimpulkan daripada dua kelas yang terpisah: WriteText dan UpdateText .

Pada hakikatnya, kami mendapat dua kelas yang digabungkan dengan erat dan padat , yang hampir selalu dapat digunakan bersama. Ketiga-tiga kaedah ini mungkin menjalankan operasi yang berbeza, tetapi pada dasarnya mereka melayani satu tujuan : Manipulasi teks. Kuncinya adalah untuk tidak berfikir secara berlebihan.

Salah satu alat yang dapat membantu mencapai kohesi tinggi dalam kaedah adalah LCOM. Pada asasnya, LCOM mengukur hubungan antara komponen kelas dan hubungannya antara satu sama lain.

Martin Hitz dan Behzad Montazeri memperkenalkan LCOM4, ​​yang Sonarqube mengukur selama beberapa waktu, tetapi sejak itu tidak lagi digunakan.

5. Kesimpulan

Walaupun nama prinsipnya cukup jelas, kita dapat melihat betapa mudahnya pelaksanaannya tidak betul. Pastikan untuk membezakan tanggungjawab setiap kelas semasa membangunkan projek dan beri perhatian yang lebih kepada kohesi.

Seperti biasa, kodnya terdapat di GitHub.