Prinsipp om enkeltansvar i Java

1. Oversikt

I denne opplæringen vil vi diskutere Single Responsibility Principle, som et av SOLID-prinsippene for objektorientert programmering.

Samlet sett vil vi gå grundig gjennom hva dette prinsippet er og hvordan vi implementerer det når vi designer programvaren vår. Videre vil vi forklare når dette prinsippet kan være misvisende.

* SRP = enkeltansvarsprinsipp

2. Enkelt ansvarsprinsipp

Som navnet antyder, sier dette prinsippet det hver klasse skal haett ansvar, ett enkelt formål. Dette betyr at en klasse bare vil gjøre en jobb, noe som får oss til å konkludere med at den burde ha bare en grunn til å endre.

Vi vil ikke ha gjenstander som vet for mye og som ikke har noe å gjøre. Disse klassene er vanskeligere å vedlikeholde. For eksempel, hvis vi har en klasse som vi endrer mye, og av forskjellige grunner, bør denne klassen deles opp i flere klasser, som hver håndterer en enkelt bekymring. Sikkert, hvis det oppstår en feil, vil det være lettere å finne den.

La oss se på en klasse som inneholder kode som endrer teksten på en eller annen måte. Den eneste jobben i denne klassen burde være manipulere tekst.

offentlig klasse TextManipulator {privat strengtekst; offentlig TextManipulator (strengtekst) {this.text = tekst; } offentlig String getText () {returtekst; } offentlig tomrom appendText (String newText) {text = text.concat (newText); } public String findWordAndRlace (String word, String replacementWord) {if (text.contains (word)) {text = text.replace (word, replacementWord); } returnere tekst; } public String findWordAndDelete (String word) {if (text.contains (word)) {text = text.replace (word, ""); } returnere tekst; } public void printText () {System.out.println (textManipulator.getText ()); }}

Selv om dette kan virke greit, er det ikke et godt eksempel på SRP. Her har vi toansvar: manipulere og skrive ut teksten.

Å ha en metode som skriver ut tekst i denne klassen, bryter med prinsippet om enkelt ansvar. For dette formålet bør vi opprette en annen klasse som bare håndterer utskrift av tekst:

offentlig klasse TextPrinter {TextManipulator textManipulator; offentlig 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)); }}

Nå, i denne klassen, kan vi lage metoder for så mange varianter av utskrift av tekst som vi vil, for det er jobben.

3. Hvordan kan dette prinsippet bli villedende?

Trikset med å implementere SRP i programvaren vår er å vite ansvaret av hver klasse.

Derimot, hver utvikler har sin visjon om klassens formål, noe som gjør ting vanskelig. Siden vi ikke har strenge instruksjoner om hvordan vi skal implementere dette prinsippet, sitter vi igjen med våre tolkninger av hva ansvaret vil være.

Hva dette betyr er at noen ganger bare vi som designere av applikasjonen kan bestemme om noe er innenfor rammen av en klasse eller ikke.

Når vi skriver en klasse i henhold til SRP-prinsippet, må vi tenke på problemdomenet, forretningsbehov og applikasjonsarkitektur. Det er veldig subjektivt, noe som gjør det vanskeligere å implementere dette prinsippet. Det vil ikke være så enkelt som eksemplet vi har i denne opplæringen.

Dette fører oss til neste punkt.

4. Samhold

I følge SRP-prinsippet vil klassene våre følge en funksjonalitet. Deres metoder og data vil være opptatt av ett klart formål. Dette betyr høy kohesjon, i tillegg til robusthet, som til sammen reduserer feil.

Når vi designer programvare basert på SRP-prinsippet, er samhold viktig, siden det hjelper oss å finne et enkelt ansvar for klassene våre. Dette konseptet hjelper oss også med å finne klasser som har mer enn ett ansvar.

La oss gå tilbake til vår TextManipulator klassemetoder:

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

Her har vi en klar fremstilling av hva denne klassen gjør: Tekstmanipulering.

Men hvis vi ikke tenker på samhørighet og ikke har en klar definisjon av hva denne klassens ansvar er, kan vi si at skriving og oppdatering av teksten er to forskjellige og separate jobber. Ledet av denne tanken kan vi konkludere med at disse burde være to separate klasser: Skriv tekst og UpdateText.

I virkeligheten ville vi fått det to klasser som er tett sammenkoblet og løst sammenhengende, som nesten alltid skal brukes sammen. Disse tre metodene kan utføre forskjellige operasjoner, men de tjener i hovedsak ett enkelt formål: Tekstmanipulering. Nøkkelen er ikke å tenke over.

Et av verktøyene som kan bidra til å oppnå høy sammenheng i metoder er LCOM. I hovedsak, LCOM måler sammenhengen mellom klassekomponenter og deres forhold til hverandre.

Martin Hitz og Behzad Montazeri introduserte LCOM4, ​​som Sonarqube målte en stund, men har siden avviklet.

5. Konklusjon

Selv om navnet på prinsippet er selvforklarende, kan vi se hvor enkelt det er å implementere feil. Sørg for å skille ut ansvaret til hver klasse når du utvikler et prosjekt, og vær ekstra oppmerksom på samhold.

Som alltid er koden tilgjengelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found