{"id":34828,"date":"2019-10-31T22:00:38","date_gmt":"2019-10-31T19:00:38","guid":{"rendered":"https:\/\/prohoster.info\/blog\/single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya\/"},"modified":"2019-10-31T22:00:38","modified_gmt":"2019-10-31T19:00:38","slug":"single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya","status":"publish","type":"post","link":"https:\/\/prohoster.info\/da\/blog\/news\/single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya","title":{"rendered":"Single Responsibility Principle. Ikke s\u00e5 enkelt, som det ser ud","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Single Responsibility Principle. Ikke s\u00e5 enkelt, som det ser ud\" src=\"\/wp-content\/uploads\/2019\/06\/5b253ff55e3c97b6baf5f7a7ae7f3b98.JPG\" style=\"display:block;margin: 0 auto;\" \/> Princippet om enkelt ansvar, ogs\u00e5 kendt som princip om enkelt ansvar,<br \/>\ndet samme, som princip om enkelt forandringsdygtighed \u2014 en yderst glat og kompleks koncept, der ofte er et nervepirrende emne i en programmerers jobsamtale. <\/p>\n<p><\/p>\n<p>Min f\u00f8rste seri\u00f8se forbindelse til dette princip skete i starten af mit f\u00f8rste semester, da vi, unge og usikre, blev taget med ud i skoven for at g\u00f8re os fra studenterlarver til rigtige studerende.<\/p>\n<p><\/p>\n<p>I skoven blev vi delt op i grupper af 8-9 personer hver, og der blev afholdt en konkurrence \u2014 hvilken gruppe kunne hurtigst drikke en flaske vodka under foruds\u00e6tning af, at den f\u00f8rste person h\u00e6lder vodka i et glas, den anden drikker, og den tredje spiser noget. Den, der har udf\u00f8rt sin opgave, stiller sig bagerst i k\u00f8en. <\/p>\n<p><\/p>\n<p>En situation, hvor st\u00f8rrelsen af k\u00f8en var et multiplum af tre, var en god implementering af SRP.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex> <\/p>\n<h2 id=\"opredelenie-1-edinaya-otvetstvennost\">Definition 1. Enkelt ansvar.<\/h2>\n<p><\/p>\n<p>Den officielle definition af princippet om enkelt ansvar (SRP) siger, at hver objekt har sit eget ansvar og eksistensberettigelse, og det ansvar er kun \u00e9n.<\/p>\n<p><\/p>\n<p>Lad os overveje objektet &#171;V\u00e6skedrengen&#187; (<strong>Tippler<\/strong>).<br \/>\nFor at overholde princippet om SRP skal vi dele opgaverne mellem tre: <\/p>\n<p><\/p>\n<ul>\n<li>En h\u00e6lder (<strong>PourOperation<\/strong>)<\/li>\n<li>En drikker (<strong>DrinkUpOperation<\/strong>)<\/li>\n<li>En spiser (<strong>TakeBiteOperation<\/strong>)<\/li>\n<\/ul>\n<p><\/p>\n<p>Hver deltager i processen er ansvarlig for \u00e9n komponent i processen, det vil sige har \u00e9t atomar ansvar \u2014 at drikke, h\u00e6lde eller spise. <\/p>\n<p><\/p>\n<p>Tippler er i sin tur en facade for disse operationer:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">class Tippler {\n    \/\/...\n    void Act(){\n        _pourOperation.Do() \/\/ h\u00e6lde\n        _drinkUpOperation.Do() \/\/ drikke\n        _takeBiteOperation.Do() \/\/ spise\n    }\n}<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Single Responsibility Principle. Ikke s\u00e5 enkelt, som det ser ud\" src=\"\/wp-content\/uploads\/2019\/06\/8d591a474e3555edfee3ffebc28d079b.JPG\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h4 id=\"zachem\">Hvorfor?<\/h4>\n<p><\/p>\n<p>Mennesket-programm\u00f8r skriver kode til mennesket-abe, og mennesket-abe er uopm\u00e6rksom, dum og altid i hast. Han kan holde og forst\u00e5 omkring 3 til 7 termer ad gangen.<br \/>\nI tilf\u00e6lde af Tippler er der tre termer. Dog, hvis vi skriver koden i \u00e9n lang r\u00e6kke, vil der komme h\u00e6nder, glas, slagsm\u00e5l og uendelige diskussioner om politik. Alt dette vil v\u00e6re inde i \u00e9n metode. Jeg er sikker p\u00e5, at du har set s\u00e5dan kode i din praksis. Det er ikke den mest humane pr\u00f8velse for psyken.<\/p>\n<p><\/p>\n<p>P\u00e5 den anden side er menneske-abemanden fokuseret p\u00e5 at modellere objekter fra den virkelige verden i sit hoved. I sin fantasi kan han kollidere dem, samle nye objekter fra dem og nedbryde dem p\u00e5 samme m\u00e5de. Forestil dig en gammeldags bilmodel. Du kan i din fantasi \u00e5bne d\u00f8ren, skrue efterbehandlingen af d\u00f8ren af og se mekanismerne i vinduerne, hvor gearene vil v\u00e6re indeni. Men du kan ikke se alle bilens komponenter p\u00e5 \u00e9n gang i en &#171;oversigt&#187;. I det mindste kan &#171;menneske-abemanden&#187; ikke.<\/p>\n<p><\/p>\n<p>Derfor dekomponerer programm\u00f8rmennesker komplekse mekanismer i et s\u00e6t mindre komplekse og funktionerende elementer. Men dekomponering kan g\u00f8res p\u00e5 forskellige m\u00e5der: i mange gamle biler \u2013 g\u00e5r luftkanalen ind i d\u00f8ren, mens i moderne biler en fejl i l\u00e5seelektronikken forhindrer motoren i at starte, hvilket g\u00f8r reparationen vanskelig.<\/p>\n<p><\/p>\n<p>S\u00e5 <strong>SRP er et princip, der forklarer HVORDAN man dekomponerer, det vil sige, hvor man skal drage skillelinjen.<\/strong>. <\/p>\n<p><\/p>\n<p>Han siger, at nedbrydning skal ske efter princippet om &#171;ansvarsfordeling&#187;, det vil sige efter opgaverne for de enkelte objekter.<\/p>\n<p>\n<img decoding=\"async\" alt=\"Single Responsibility Principle. Ikke s\u00e5 enkelt, som det ser ud\" src=\"\/wp-content\/uploads\/2019\/06\/b1980c3dc9742b921eb818f14fe3527e.JPG\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Lad os vende tilbage til drikeren og de fordele, som menneske-aberen f\u00e5r ved dekomponering: <\/p>\n<p><\/p>\n<ul>\n<li>Koden bliver fuldst\u00e6ndig klar p\u00e5 hvert niveau.<\/li>\n<li>Koden kan skrives af flere programm\u00f8rer samtidig (hver skriver et separat element).<\/li>\n<li>Automatisk testning forenkles \u2013 jo enklere elementet er, desto lettere er det at teste det.<\/li>\n<li>Der opst\u00e5r komposition af kode \u2013 man kan erstatte <strong>DrinkUpOperation<\/strong> med en operation, hvor drikeren h\u00e6lder v\u00e6sken ud under bordet. Eller erstatte h\u00e6ldningen med en operation, hvor man blander vin og vand eller vodka og \u00f8l. Afh\u00e6ngigt af forretningskravene kan man g\u00f8re alt dette uden at r\u00f8re ved metoden. <strong>Tippler.Act<\/strong>. <\/li>\n<li>Ud af disse operationer kan du sammens\u00e6tte en gumse (ved kun at bruge <strong>TakeBitOperation<\/strong>), en alkoholiker (ved kun at bruge <strong>DrinkUpOperation<\/strong> direkte fra flasken) og opfylde mange andre forretningskrav.<\/li>\n<\/ul>\n<p><\/p>\n<p><em>(\u00c5h, det ser ud til, at dette allerede er OCP-princippet, og jeg har kr\u00e6nket ansvaret for dette indl\u00e6g.) <\/em><\/p>\n<p><\/p>\n<p>Og selvf\u00f8lgelig ulemperne: <\/p>\n<p><\/p>\n<ul>\n<li>Man bliver n\u00f8dt til at oprette flere typer. <\/li>\n<li>Drikeren vil drikke et par timer senere end han kunne have.<\/li>\n<\/ul>\n<p><\/p>\n<h2 id=\"opredelenie-2-edinaya-izmenchivost\">Definition 2. Enhedlig foranderlighed.<\/h2>\n<p><\/p>\n<p>Tillad mig, mine herrer! Klassen for v\u00e6skedrengen udf\u00f8rer ogs\u00e5 et enkelt ansvar \u2014 han drikker! Og generelt er ordet &#171;ansvar&#187; et ekstremt vag koncept. Nogen er ansvarlig for menneskehedens sk\u00e6bne, mens andre er ansvarlige for at rejse de v\u00e6ltede pingviner p\u00e5 polen.<\/p>\n<p><\/p>\n<p>Lad os se p\u00e5 to implementeringer af drikeren. Den f\u00f8rste, n\u00e6vnt ovenfor, indeholder tre klasser \u2014 h\u00e6ld, drik og snack.<\/p>\n<p><\/p>\n<p>Det andet, skrevet gennem metodologien &#171;Fremad og kun fremad&#187; og indeholder al logik i metoden <strong>Act<\/strong>:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">\/\/\u041d\u0435 \u0442\u0440\u0430\u0442\u044c\u0442\u0435 \u0432\u0440\u0435\u043c\u044f  \u043d\u0430 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430. \u041b\u0443\u0447\u0448\u0435 \u0441\u044a\u0435\u0448\u044c\u0442\u0435 \u043f\u0435\u0447\u0435\u043d\u044c\u043a\u0443\n\u0441lass BrutTippler {\n   \/\/...\n   void Act(){\n        \/\/ \u043d\u0430\u043b\u0438\u0432\u0430\u0435\u043c\n    if(!_hand.TryDischarge(from:_bottle, to:_glass, size:_glass.Capacity))\n        throw new OverdrunkException();\n\n    \/\/ \u0432\u044b\u043f\u0438\u0432\u0430\u0435\u043c\n    if(!_hand.TryDrink(from: _glass,  size: _glass.Capacity))\n        throw new OverdrunkException();\n\n    \/\/\u0417\u0430\u043a\u0443\u0441\u044b\u0432\u0430\u0435\u043c\n    for(int i = 0; i&lt; 3; i++){\n        var food = _foodStore.TakeOrDefault();\n        if(food==null)\n            throw new FoodIsOverException();\n\n        _hand.TryEat(food);\n    }\n   }\n}<\/code><\/pre>\n<p><\/p>\n<p>Begge disse klasser ser ud fra en tredjeparts observer umiddelbart ens ud og udf\u00f8rer et enkelt ansvar &#171;drikke&#187;. <\/p>\n<p><\/p>\n<p>Pinligt!<\/p>\n<p><\/p>\n<p>S\u00e5 graver vi i internettet og opdager en anden definition af SRP \u2014 Det enkle \u00e6ndringsprincip (Single Changeability Principle).<\/p>\n<p><\/p>\n<p>SCP siger, at &#171;<strong>Modulet har kun \u00e9n og kun \u00e9n grund til at \u00e6ndre sig<\/strong>&#171;. Det vil sige &#171;Ansvar er en grund til \u00e6ndring&#187;. <\/p>\n<p><\/p>\n<p><em>(Det lader til, at drengene, der i f\u00f8rste omgang opfandt definitionen, var sikre p\u00e5 menneske-abens telepatiske evner)<\/em><\/p>\n<p><\/p>\n<p>Nu falder alt p\u00e5 plads. Separat kan vi \u00e6ndre procedurerne for h\u00e6ldning, drikning og snacks, og i selve drikeren kan vi kun \u00e6ndre r\u00e6kkef\u00f8lgen og indholdet af operationerne, for eksempel ved at flytte snacks f\u00f8r drikning eller tilf\u00f8je l\u00e6sning af en sk\u00e5l.<\/p>\n<p><\/p>\n<p>I tilgangen &#171;Fremad og kun fremad&#187;, \u00e6ndres alt, hvad der kan \u00e6ndres, kun i metoden <strong>Act<\/strong>. Dette kan v\u00e6re l\u00e6sevenligt og effektivt i tilf\u00e6lde, hvor logikken er sparsom og sj\u00e6ldent \u00e6ndres, men ofte ender det med forf\u00e6rdelige metoder p\u00e5 500 linjer hver med et antal if-er st\u00f8rre end n\u00f8dvendigt for Ruslands optagelse i NATO. <\/p>\n<p><\/p>\n<h2 id=\"opredelenie-3-lokalizaciya-izmeneniy\">Definition 3. Lokalisering af \u00e6ndringer.<\/h2>\n<p><\/p>\n<p>Drikere forst\u00e5r ofte ikke, hvorfor de v\u00e5gner op i en fremmed lejlighed, eller hvor deres mobiltelefon er. Det er tid til at tilf\u00f8je detaljeret logning.<\/p>\n<p><\/p>\n<p>Lad os starte logningen med h\u00e6ldningsprocessen:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">class PourOperation: IOperation{\n    PourOperation(ILogger log \/*....*\/){\/*...*\/}\n    \/\/...\n    void Do(){\n        _log.Log($\"F\u00f8r h\u00e6ldning med {_hand} og {_bottle}\");\n        \/\/H\u00e6ld forretningslogik ...\n        _log.Log($\"Efter h\u00e6ldning med {_hand} og {_bottle}\");\n    }\n}<\/code><\/pre>\n<p><\/p>\n<p>Ved at kapsle det ind i <strong>PourOperation<\/strong>, vi handlede klogt med hensyn til ansvar og indkapsling, men nu har vi et dilemma med hensyn til \u00e6ndrede krav. Udover selve operationen, som kan \u00e6ndre sig, bliver logningen ogs\u00e5 variabel. Vi m\u00e5 adskille og lave en specialiseret logger til h\u00e6ldningsoperationen:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">interface IPourLogger{\n    void LogBefore(IHand, IBottle){}\n    void LogAfter(IHand, IBottle){}\n    void OnError(IHand, IBottle, Exception){}\n}\n\nclass PourOperation: IOperation{\n    PourOperation(IPourLogger log \n\/*....*\/){\n\/*...*\/}\n    \/\/...\n    void Do(){\n        _log.LogBefore(_hand, _bottle);\n        try{\n             \/\/... forretningslogik\n             _log.LogAfter(_hand, _bottle\");\n        }\n        catch(exception e){\n            _log.OnError(_hand, _bottle, e)\n        }\n    }\n}<\/code><\/pre>\n<p><\/p>\n<p>Den nysgerrige l\u00e6ser vil bem\u00e6rke, at <strong>LogAfter<\/strong>, <strong>LogBefore<\/strong> og <strong>OnError<\/strong> kan ogs\u00e5 \u00e6ndre sig individuelt, og ligesom med tidligere handlinger vil det skabe tre klasser: <strong>PourLoggerBefore<\/strong>, <strong>PourLoggerAfter<\/strong> og <strong>PourErrorLogger<\/strong>.<\/p>\n<p><\/p>\n<p>Og hvis vi husker, at der er tre operationer for h\u00e6lderen \u2014 f\u00e5r vi ni loggingsklasser. I alt best\u00e5r h\u00e6lderen af 14 (!!!) klasser.<\/p>\n<p><\/p>\n<p>Hyperbel? N\u00e6ppe! Mennesket-aber med en dekompositionsgranat vil smuldre 'h\u00e6lderen' ned i karaflen, glas, h\u00e6ldningsoperat\u00f8rer, vandservices, den fysiske model for molekylekollisioner, og n\u00e6ste kvartal vil fors\u00f8ge at rede afh\u00e6ngighederne uden globale variable. Og tro mig \u2014 han stopper ikke.<\/p>\n<p><\/p>\n<p>Netop i dette \u00f8jeblik n\u00e5r mange frem til den konklusion, at SRP er eventyr fra de lyser\u00f8de riger, og g\u00e5r hen og vrider nudler...<\/p>\n<p><\/p>\n<p>\u2026 uden nogensinde at l\u00e6re om eksistensen af den tredje definition af SRP: <\/p>\n<p><\/p>\n<p>&#171;Princip for enkelt ansvar siger, at <strong>relaterede ting, der skal \u00e6ndres, b\u00f8r opbevares \u00e9t sted<\/strong>&#171;. eller \u201c<strong>Det, der \u00e6ndrer sig sammen, skal opbevares \u00e9t sted.<\/strong>\u201d<\/p>\n<p><\/p>\n<p>Det vil sige, hvis vi \u00e6ndrer logningen af operationen, s\u00e5 skal vi \u00e6ndre det \u00e9t sted.<\/p>\n<p><\/p>\n<p>Dette er et meget vigtigt punkt \u2014 da alle forklaringerne p\u00e5 SRP, som blev n\u00e6vnt f\u00f8r, talte om at man skulle opdele typer, s\u00e5 l\u00e6nge de kan opdeles, hvilket p\u00e5l\u00e6gger &#171;en \u00f8vre gr\u00e6nse&#187; for objektst\u00f8rrelsen, men nu taler vi ogs\u00e5 om &#171;en nedre gr\u00e6nse&#187;. Med andre ord, <strong>SRP kr\u00e6ver ikke kun &#171;at opdele, s\u00e5 l\u00e6nge det kan opdeles&#187;, men ogs\u00e5 at man ikke overdriver \u2014 &#171;ikke opdele sammenh\u00e6ngende ting&#187;<\/strong>. Dette er den store kamp mellem Ockhams barberblad og mennesket-aber!<\/p>\n<p>\n<img decoding=\"async\" alt=\"Single Responsibility Principle. Ikke s\u00e5 enkelt, som det ser ud\" src=\"\/wp-content\/uploads\/2019\/06\/2e349a5b119a511d716341f3f6725844.JPG\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Nu burde det blive lettere for h\u00e6lderen. Udover at vi ikke beh\u00f8ver at opdele loggeren IPourLogger i tre klasser, kan vi ogs\u00e5 samle alle loggere i \u00e9n type:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">class OperationLogger{\n    public OperationLogger(string operationName){\n \/*..*\/}\n    public void LogBefore(object[] args){\n \/*...*\/}\n    public void LogAfter(object[] args){\n \/*..*\/}\n    public void LogError(object[] args, exception e){\n \/*..*\/}\n}<\/code><\/pre>\n<p><\/p>\n<p>Og hvis vi tilf\u00f8jer en fjerde type operation, s\u00e5 er logningen allerede klar til den. Og koden for selve operationerne er ren og fri for infrastrukturs st\u00f8j.<\/p>\n<p><\/p>\n<p>Som et resultat har vi 5 klasser til at l\u00f8se problemet med at h\u00e6lde:<\/p>\n<p><\/p>\n<ul>\n<li>H\u00e6ldningsoperation<\/li>\n<li>Drikningsoperation<\/li>\n<li>Spisningoperation<\/li>\n<li>Logger<\/li>\n<li>Facade for druk<\/li>\n<\/ul>\n<p><\/p>\n<p>Hver af dem har et strengt ansvar for en funktionalitet og har kun \u00e9n \u00e5rsag til at \u00e6ndre sig. Alle lignende \u00e6ndringsregler ligger t\u00e6t sammen. <\/p>\n<p>\n<b class=\"spoiler_title\">Eksempel fra det virkelige liv<\/b><\/p>\n<p>Engang skrev vi en tjeneste til automatisk registrering af b2b-kunder. Og der opstod en GOD-metode p\u00e5 200 linjer med lignende indhold:<\/p>\n<p><\/p>\n<ul>\n<li>G\u00e5 til 1C og opret en konto<\/li>\n<li>Med denne konto, g\u00e5 til betalingsmodulet og opret den der<\/li>\n<li>Tjek at en konto med denne nummer ikke er oprettet i hovedsystemet <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/da\/server\/dts-dronten\/\"   title=\"serveren\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"2485\">serveren<\/a><\/li>\n<li>Opret en ny konto<\/li>\n<li>Resultatet af registreringen i betalingsmodulet og nummeret fra 1C tilf\u00f8j til registreringsresultatstjenesten<\/li>\n<li>Tilf\u00f8j oplysninger om kontoen til denne tabel<\/li>\n<li>Opret et punktnummer for denne kunde i tjenesten for punkter. Overf\u00f8r kontonummeret fra 1C til denne tjeneste.<\/li>\n<\/ul>\n<p><\/p>\n<p>Og der var i denne liste omkring 10 andre forretningsoperationer med forf\u00e6rdelig sammenh\u00e6ng. Kontoobjektet var n\u00f8dvendigt for n\u00e6sten alle. Punktidentifikatoren og kundens navn var p\u00e5kr\u00e6vet i halvdelen af opkaldene.<\/p>\n<p><\/p>\n<p>Efter en times refaktorering kunne vi adskille infrastrukturkode og nogle nuancer vedr\u00f8rende arbejdet med kontoen i separate metoder\/klasser. Godmetoden blev lettere, men der var stadig 100 linjer kode, der ikke ville tr\u00e6kke sig tilbage. <\/p>\n<p><\/p>\n<p>F\u00f8rst efter nogle dage kom forst\u00e5elsen af, at essensen af denne &#171;lettede&#187; metode \u2014 er den forretningsm\u00e6ssige algoritme. Og at den oprindelige beskrivelse af kravene var temmelig kompleks. Og netop fors\u00f8get p\u00e5 at opdele denne metode i bidder vil v\u00e6re en overtr\u00e6delse af SRP, og ikke det modsatte. <\/p>\n<p><\/p>\n<h2 id=\"formalizm\">Formalismen.<\/h2>\n<p><\/p>\n<p>Det er tid til at give vores drukker en pause. T\u00f8r t\u00e5rerne \u2014 vi vil helt sikkert vende tilbage til ham en dag. Men nu skal vi formaliserer viden fra denne artikel. <\/p>\n<p><\/p>\n<h4 id=\"formalizm-1-opredelenie-srp\">Formalismen 1. Definition af SRP<\/h4>\n<p><\/p>\n<ol>\n<li>Opdel elementer s\u00e5ledes, at hver enkelt har ansvar for noget enkelt.<\/li>\n<li>Ansvar defineres som \u00abgrund til \u00e6ndring\u00bb. Det vil sige, at hvert element kun har \u00e9n grund til \u00e6ndring, i termer af forretningslogik.<\/li>\n<li>Potentielle \u00e6ndringer i forretningslogikken skal lokaliseres. \u00c6ndrede synkroniserede elementer skal v\u00e6re t\u00e6t p\u00e5 hinanden.<\/li>\n<\/ol>\n<p><\/p>\n<h4 id=\"formalizm-2-neobhodimye-kriterii-samoproverki\">Formalisme 2. N\u00f8dvendige kriterier for selvkontrol.<\/h4>\n<p><\/p>\n<p>Jeg har ikke set tilstr\u00e6kkelige kriterier for opfyldelse af SRP. Men der er n\u00f8dvendige betingelser:<\/p>\n<p><\/p>\n<p>1) Stil dig selv sp\u00f8rgsm\u00e5let \u2013 hvad g\u00f8r denne klasse\/metode\/modul\/tjeneste. Du skal kunne besvare det med en enkel definition. (tak) <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/brightori\/\" class=\"user_link\">Brightori<\/a><\/noindex> )<\/p>\n<p>\n<b class=\"spoiler_title\">forklaringer<\/b><\/p>\n<p>Det kan dog nogle gange v\u00e6re meget sv\u00e6rt at finde en enkel definition. <\/p>\n<p><\/p>\n<p>2) Fiksering af en bestemt fejl eller tilf\u00f8jelse af en ny funktion ber\u00f8rer et minimum af filer\/klasser. Ideelt set \u2013 \u00e9n. <\/p>\n<p>\n<b class=\"spoiler_title\">forklaringer<\/b><\/p>\n<p>Da ansvaret (for funktionen eller fejlen) er indkapslet i \u00e9n fil\/klasse, ved du pr\u00e6cist, hvor du skal lede og hvad du skal rette. For eksempel: en funktion til at \u00e6ndre logningen af operationer kr\u00e6ver kun \u00e6ndring af loggertjenesten. Det er ikke n\u00f8dvendigt at s\u00f8ge i den \u00f8vrige kode. <\/p>\n<p><\/p>\n<p>Et andet eksempel \u2013 tilf\u00f8jelse af en ny UI-kontrol, der ligner de tidligere. Hvis det f\u00e5r dig til at tilf\u00f8je 10 forskellige enheder og 15 forskellige konvertere \u2013 ser det ud til, at du er 'overkompliceret'.<\/p>\n<p><\/p>\n<p>3) Hvis flere udviklere arbejder p\u00e5 forskellige funktioner i dit projekt, er sandsynligheden for merge-konflikter, alts\u00e5 sandsynligheden for, at den samme fil\/klasse \u00e6ndres af flere udviklere samtidig \u2013 minimal.<\/p>\n<p>\n<b class=\"spoiler_title\">forklaringer<\/b><\/p>\n<p>Hvis det ved tilf\u00f8jelse af en ny operation \u00abH\u00e6lde vodka under bordet\u00bb er n\u00f8dvendigt at ber\u00f8re logning, drikke- og h\u00e6ldningsoperationerne, s\u00e5 tyder det p\u00e5, at ansvaret er sk\u00e6vt fordelt. Det er bestemt ikke altid muligt, men man b\u00f8r str\u00e6be efter at reducere denne indikator. <\/p>\n<p><\/p>\n<p>4) Ved et pr\u00e6ciserende sp\u00f8rgsm\u00e5l om forretningslogik (fra udvikleren eller lederen) dykker du strengt ned i \u00e9n klasse\/fil og f\u00e5r kun information derfra.<\/p>\n<p>\n<b class=\"spoiler_title\">forklaringer<\/b><\/p>\n<p>Funktioner, regler eller algoritmer er kompakt skrevet, hver p\u00e5 \u00e9t sted, og ikke spredt som flag over hele kodebasen.<\/p>\n<p><\/p>\n<p>5) Navngivning er forst\u00e5elig.<\/p>\n<p>\n<b class=\"spoiler_title\">forklaringer<\/b><\/p>\n<p>Vores klasse eller metode er ansvarlig for \u00e9n ting, og ansvaret afspejles i dens navn.<\/p>\n<p><\/p>\n<p>AllManagersManagerService \u2013 sandsynligvis en God-klasse.<br \/>\nLocalPayment \u2013 sandsynligvis ikke. <\/p>\n<p><\/p>\n<h4 id=\"formalizm-3-metodika-razrabotki-okkama-first\">Formalismen 3. Udviklingsmetoden \u00abOccam-first\u00bb.<\/h4>\n<p><\/p>\n<p>I begyndelsen af designet ved eller f\u00f8ler menneske-aberne ikke alle nuancerne i den stillede opgave og kan lave fejl. Man kan fejle p\u00e5 forskellig vis:<\/p>\n<p><\/p>\n<ul>\n<li>At skabe for store objekter ved at kombinere forskellige ansvarsomr\u00e5der<\/li>\n<li>At overfragmentere ved at dele et enkelt ansvar op i mange forskellige typer<\/li>\n<li>At definere gr\u00e6nserne for ansvar forkert<\/li>\n<\/ul>\n<p><\/p>\n<p>Det er vigtigt at huske reglen: \u00abdet er bedre at fejle i den store retning\u00bb, eller \u00aber du usikker \u2014 s\u00e5 del ikke op\u00bb. Hvis for eksempel din klasse samler to ansvarsomr\u00e5der \u2014 s\u00e5 er den stadig forst\u00e5elig, og den kan opdeles i to med minimal \u00e6ndring af klientkoden. At samle et glas fra glassk\u00e5r er som regel sv\u00e6rere p\u00e5 grund af den uklarhed, der er spredt over flere filer og manglen p\u00e5 n\u00f8dvendige afh\u00e6ngigheder i klientkoden. <\/p>\n<p><\/p>\n<h2 id=\"pora-zakruglyatsya\">Det er tid til at runde af<\/h2>\n<p><\/p>\n<p>Anvendelsesomr\u00e5det for SRP er ikke begr\u00e6nset til OOP og SOLID. Det g\u00e6lder metoder, funktioner, klasser, moduler, mikrotjenester og tjenester. Det g\u00e6lder b\u00e5de for 'fighax-fighax-og-til-produkt' samt 'rocket-science' udvikling, og g\u00f8r verden lidt bedre overalt. Hvis man t\u00e6nker over det, er det n\u00e6ppe andet end en grundl\u00e6ggende princip i hele ingeni\u00f8rfaget. Maskinbygning, kontrolsystemer og alle komplekse systemer bygges af komponenter, og 'underfragmentering' ber\u00f8ver konstrukt\u00f8rer fleksibilitet, 'overfragmentering' - effektivitet, og forkerte gr\u00e6nser - fornuft og indre fred. <\/p>\n<p>\n<img decoding=\"async\" alt=\"Single Responsibility Principle. Ikke s\u00e5 enkelt, som det ser ud\" src=\"\/wp-content\/uploads\/2019\/06\/b70fb2b0b87cf90d41462263e839902b.JPG\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>SRP er ikke noget, der er opfundet af naturen, og det er ikke en del af pr\u00e6cise videnskaber. Det stammer fra vores biologiske og psykologiske begr\u00e6nsninger. Det er blot en m\u00e5de at kontrollere og udvikle komplekse systemer ved hj\u00e6lp af det menneskelige primats hjerne. Det fort\u00e6ller os, hvordan man dekomponerer et system. Den oprindelige formulering kr\u00e6vede en god portion telepati, men jeg h\u00e5ber, denne artikel let kan klare t\u00e5gen.<\/p>\n<p>Kilde: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/454290\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>Single responsibility principle, \u043e\u043d \u0436\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0435\u0434\u0438\u043d\u043e\u0439 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438, \u043e\u043d \u0436\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0435\u0434\u0438\u043d\u043e\u0439 \u0438\u0437\u043c\u0435\u043d\u0447\u0438\u0432\u043e\u0441\u0442\u0438 \u2014 \u043a\u0440\u0430\u0439\u043d\u0435 \u0441\u043a\u043e\u043b\u044c\u0437\u043a\u0438\u0439 \u0434\u043b\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043f\u0430\u0440\u0435\u043d\u044c \u0438 \u0441\u0442\u043e\u043b\u044c \u043d\u0435\u0440\u0432\u043e\u0437\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 \u043d\u0430 \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430. \u041f\u0435\u0440\u0432\u043e\u0435 \u0441\u0435\u0440\u044c\u0435\u0437\u043d\u043e\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e \u0441 \u044d\u0442\u0438\u043c \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043b\u043e\u0441\u044c \u0434\u043b\u044f \u043c\u0435\u043d\u044f \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043a\u0443\u0440\u0441\u0430, \u043a\u043e\u0433\u0434\u0430 \u043c\u043e\u043b\u043e\u0434\u044b\u0445 \u0438 \u0437\u0435\u043b\u0435\u043d\u044b\u0445 \u043d\u0430\u0441 \u0432\u044b\u0432\u0435\u0437\u043b\u0438 \u0432 \u043b\u0435\u0441, \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0437 \u043b\u0438\u0447\u0438\u043d\u043e\u043a \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u043e\u0432 \u2014 \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u043e\u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0445. [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":26229,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[702],"tags":[],"class_list":["post-34828","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-news"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/da\/blog\/news\/single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"da_DK\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47Single Responsibility Principle. \u041d\u0435 \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u043a\u0430\u043a \u043a\u0430\u0436\u0435\u0442\u0441\u044f | ProHoster\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/da\/blog\/news\/single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:00:38+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:00:38+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Single Responsibility Principle. Ikke s\u00e5 enkelt som det ser ud | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/da\/blog\/news\/single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"da_DK","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47Single Responsibility Principle. \u041d\u0435 \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u043a\u0430\u043a \u043a\u0430\u0436\u0435\u0442\u0441\u044f | ProHoster","og:url":"https:\/\/prohoster.info\/da\/blog\/news\/single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:00:38+00:00","article:modified_time":"2019-10-31T19:00:38+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"34828","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-02-09 21:46:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 02:14:06","updated":"2026-02-09 21:46:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/34828","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/comments?post=34828"}],"version-history":[{"count":1,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/34828\/revisions"}],"predecessor-version":[{"id":159767,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/34828\/revisions\/159767"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media\/26229"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media?parent=34828"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/categories?post=34828"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/tags?post=34828"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}