Egyetlen felelősség elve a Java-ban

1. Áttekintés

Ebben az oktatóanyagban az Egységes Felelősség Elvet fogjuk megvitatni, mint az objektumorientált programozás egyik SOLID elvét.

Összességében a szoftverünk megtervezésekor elmélyülten megvizsgáljuk, hogy mi ez az elv és hogyan kell azt megvalósítani. Ezenkívül elmagyarázzuk, hogy ez az elv mikor lehet félrevezető.

* SRP = Egységes Felelősség Elve

2. Egyetlen felelősség elve

Ahogy a neve is sugallja, ez az elv azt állítja minden osztálynak rendelkeznie kellegy felelősség, egyetlen cél. Ez azt jelenti, hogy egy osztály csak egy munkát fog végezni, ami arra enged következtetni, hogy annak kellett volna lennie csak egy oka van a változásra.

Nem akarunk olyan tárgyakat, amelyek túl sokat tudnak és nem viselkednek egymással. Ezeket az osztályokat nehezebb fenntartani. Például, ha van olyan osztályunk, amelyet sokat változtatunk, és különböző okokból kifolyólag, akkor ezt az osztályt több osztályra kell bontani, mindegyiknek egyetlen gondot kell kezelnie. Biztosan, ha hiba történik, akkor könnyebb megtalálni.

Vegyünk egy osztályt, amely olyan kódot tartalmaz, amely valamilyen módon megváltoztatja a szöveget. Ennek az osztálynak egyetlen feladata az kell, hogy legyen a szöveg manipulálása.

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 (karakterlánc szó, String helyettesítő szó) {if (szöveg.tartalmaz (szó)) {szöveg = szöveg.replace (szó, helyettesítő szó); } visszatérő szöveg; } public String findWordAndDelete (karakterlánc szó) {if (text.contains (word)) {text = text.replace (word, ""); } visszatérő szöveg; } public void printText () {System.out.println (textManipulator.getText ()); }}

Bár ez jónak tűnhet, mégsem jó példa az SRP-re. Itt van kettőfelelősségek: a szöveg manipulálása és nyomtatása.

Ha olyan módszer van, amely ebbe az osztályba írja ki a szöveget, megsérti az egységes felelősség elvét. Ehhez létre kell hoznunk egy másik osztályt, amely csak a szöveg nyomtatását kezeli:

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 startIndex, int endIndex) {System.out.println (textManipulator.getText (). substring (startIndex, endIndex)); }}

Most ebben az osztályban létrehozhatunk módszereket a szöveg nyomtatásának annyi változatához, amennyit csak akarunk, mert ez a feladata.

3. Hogyan lehet ez az elv félrevezető?

Az SRP szoftverünkbe való bevezetésének trükkje a felelősség ismerete minden osztályból.

Azonban, minden fejlesztőnek meglátása van az osztály céljáról, ami a dolgokat bonyolulttá teszi. Mivel nincs szigorú utasításunk ennek az elvnek a megvalósítására, ezért nekünk marad értelmezéseink arról, hogy mi lesz a felelősség.

Ez azt jelenti, hogy néha csak mi, az alkalmazásunk tervezői dönthetünk el arról, hogy valami egy osztály hatókörébe tartozik-e vagy sem.

Amikor osztályt írunk az SRP elv szerint, gondolkodnunk kell a problématerületen, az üzleti igényeken és az alkalmazás architektúráján. Nagyon szubjektív, ami megnehezíti ennek az elvnek a megvalósítását, mint amilyennek látszik. Ez nem lesz olyan egyszerű, mint az ebben az oktatóanyagban szereplő példa.

Ez a következő pontra vezet minket.

4. Összetartás

Az SRP elvét követve osztályaink egy funkciót fognak betartani. Módszereik és adataik egy világos céllal fognak foglalkozni. Ez azt jelenti, hogy magas kohézió, továbbá robusztusság, amelyek együttesen csökkentik a hibákat.

Az SRP elvén alapuló szoftver tervezésénél elengedhetetlen a kohézió, mivel ez segít abban, hogy egyetlen felelősséget találjunk osztályaink számára. Ez a koncepció abban is segít, hogy olyan osztályokat találjunk, amelyeknek több felelőssége is van.

Térjünk vissza a miénkre TextManipulator osztály módszerek:

... public void appendText (String newText) {text = text.concat (newText); } public String findWordAndReplace (karakterlánc szó, String helyettesítő szó) {if (szöveg.tartalmaz (szó)) {szöveg = szöveg.replace (szó, helyettesítő szó); } visszatérő szöveg; } public String findWordAndDelete (karakterlánc szó) {if (text.contains (word)) {text = text.replace (word, ""); } visszatérő szöveg; } ...

Itt világosan bemutatjuk, mit csinál ez az osztály: Szövegmanipuláció.

De, ha nem gondolkodunk a kohézión, és nincs egyértelmű definíciónk arról, hogy mi ennek az osztálynak a felelőssége, akkor azt mondhatnánk, hogy a szöveg írása és frissítése két különböző és különálló munka. E gondolat vezetésével arra következtethetünk, hogy ezeknek két külön osztálynak kell lenniük: WriteText és UpdateText.

A valóságban megkapnánk két szorosan összekapcsolt és lazán összetartó osztály, amelyet szinte mindig együtt kell használni. Ez a három módszer lehet különböző műveleteket végeznek, de lényegében egyetlen célt szolgálnak: Szövegmanipuláció. A legfontosabb, hogy ne gondoljuk túlzásba.

Az egyik eszköz, amely elősegítheti a módszerek magas kohézióját, az LCOM. Lényegében, Az LCOM méri az osztályösszetevők közötti kapcsolatot és azok egymáshoz való viszonyát.

Martin Hitz és Behzad Montazeri bemutatták az LCOM4-et, amelyet Sonarqube egy ideig mérett, de azóta lejáratott.

5. Következtetés

Annak ellenére, hogy az elv neve magától értetődő, láthatjuk, hogy mennyire könnyű helytelenül megvalósítani. Ügyeljen arra, hogy megkülönböztesse minden osztály felelősségét a projekt kidolgozása során, és fokozott figyelmet fordítson a kohézióra.

Mint mindig, a kód is elérhető a GitHubon.