{"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\/hr\/blog\/news\/single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya","title":{"rendered":"Jedinstveni odgovorni princip. Nije tako jednostavno kao \u0161to se \u010dini","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Jedinstveni odgovorni princip. Nije tako jednostavno kao \u0161to se \u010dini\" src=\"\/wp-content\/uploads\/2019\/06\/5b253ff55e3c97b6baf5f7a7ae7f3b98.JPG\" style=\"display:block;margin: 0 auto;\" \/> Princip jedinstvene odgovornosti, tako\u0111er poznat kao princip jedinstvene obaveze,<br \/>\ntako\u0111er poznat kao princip jedinstvene promjene \u2014 iznimno klizak za razumijevanje i vrlo nelagodno pitanje na intervjuu za programere. <\/p>\n<p><\/p>\n<p>Moje prvo ozbiljno uvjeravanje s tim principom dogodilo se na po\u010detku prve godine, kada su nas mlade i neiskusne odveli u \u0161umu kako bi od nas stvorili prave studente.<\/p>\n<p><\/p>\n<p>U \u0161umi su nas podijelili u grupe od 8-9 osoba i organizirali natjecanje \u2014 koja grupa \u0107e br\u017ee popiti bocu rakije pod uvjetom da prvi \u010dlan grupe ulije rakiju u \u010da\u0161u, drugi pije, a tre\u0107i grize. Izvr\u0161eni \u010dlan suradnje odlazi na kraj reda grupe. <\/p>\n<p><\/p>\n<p>Slu\u010daj kada je veli\u010dina reda bila vi\u0161ekratnik tri, bio je dobra realizacija SRP-a.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex> <\/p>\n<h2 id=\"opredelenie-1-edinaya-otvetstvennost\">Definicija 1. Jedinstvena odgovornost.<\/h2>\n<p><\/p>\n<p>Pravna definicija principa jedinstvene odgovornosti (SRP) ka\u017ee da svaki objekt ima svoju odgovornost i razlog postojanja, a ta odgovornost je samo jedna.<\/p>\n<p><\/p>\n<p>Razmotrite objekt &#171;Pijanica&#187; (<strong>Tippler<\/strong>).<br \/>\nZa implementaciju SRP-a podijelit \u0107emo zadu\u017eenja na troje: <\/p>\n<p><\/p>\n<ul>\n<li>Jedan ulije (<strong>PourOperation<\/strong>)<\/li>\n<li>Jedan pije (<strong>DrinkUpOperation<\/strong>)<\/li>\n<li>Jedan grize (<strong>TakeBiteOperation<\/strong>)<\/li>\n<\/ul>\n<p><\/p>\n<p>Svaki od sudionika u procesu odgovoran je za jednu komponentu procesa, tj. ima jednu atomsku odgovornost \u2014 popiti, uliti ili gristi. <\/p>\n<p><\/p>\n<p>Pijanac, s druge strane, slu\u017ei kao fasada za te operacije:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">class Tippler {\n    \/\/...\n    void Act(){\n        _pourOperation.Do() \/\/ uliti\n        _drinkUpOperation.Do() \/\/ popiti\n        _takeBiteOperation.Do() \/\/ gristi\n    }\n}<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Jedinstveni odgovorni princip. Nije tako jednostavno kao \u0161to se \u010dini\" src=\"\/wp-content\/uploads\/2019\/06\/8d591a474e3555edfee3ffebc28d079b.JPG\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h4 id=\"zachem\">Za\u0161to?<\/h4>\n<p><\/p>\n<p>Programer pi\u0161e kod za \u010dovjeka-majmun, a \u010dovjek-majmun je nepa\u017eljiv, glup i stalno negdje \u017euri. Mo\u017ee zadr\u017eati i razumjeti otprilike 3 \u2014 7 termina u jednom trenutku.<br \/>\nU slu\u010daju pijanice, ti termini su tri. Me\u0111utim, ako napi\u0161emo kod kao jednu duga\u010dku datoteku, pojavit \u0107e se ruke, \u010da\u0161e, pretu\u010dene osobe i beskrajne rasprave o politici. I sve to bit \u0107e u tijelu jedne metode. Siguran sam da ste vidjeli takav kod u svojoj praksi. Nije najhumanije isku\u0161enje za psihu.<\/p>\n<p><\/p>\n<p>S druge strane, \u010dovjek-majmuna je usredoto\u010den na modeliranje objekata stvarnog svijeta u svojoj glavi. U svojoj ma\u0161ti mo\u017ee ih sudarati, sastavljati nove objekte i isto tako ih razra\u0111ivati. Zamislite stari model automobila. Mo\u017eete u ma\u0161ti otvoriti vrata, odvrnuti oblogu vrata i vidjeti mehanizme podiza\u010da prozora, unutar kojih \u0107e biti zup\u010danici. No, ne mo\u017eete vidjeti sve komponente automobila odjednom, u jednom &#171;izlistavanju&#187;. U najmanju ruku &#171;\u010dovjek-majmuna&#187; ne mo\u017ee.<\/p>\n<p><\/p>\n<p>Stoga programeri-dekompozitori razla\u017eu slo\u017eene mehanizme na set manje slo\u017eenih i funkcionalnih elemenata. Me\u0111utim, dekompozicija se mo\u017ee raditi na razli\u010dite na\u010dine: u mnogim starim automobilima - dovod zraka izlazi u vrata, dok u modernima, kvar elektronike brave onemogu\u0107ava pokretanje motora, \u0161to predstavlja problem prilikom popravka.<\/p>\n<p><\/p>\n<p>Dakle, <strong>SRP je princip koji obja\u0161njava KAKO dekomponirati, to jest gdje povu\u0107i liniju razdvajanja.<\/strong>. <\/p>\n<p><\/p>\n<p>Ka\u017ee da se dekompozicija treba temeljiti na principu odvajanja &#171;odgovornosti&#187;, tj. prema zadacima odre\u0111enih objekata.<\/p>\n<p>\n<img decoding=\"async\" alt=\"Jedinstveni odgovorni princip. Nije tako jednostavno kao \u0161to se \u010dini\" src=\"\/wp-content\/uploads\/2019\/06\/b1980c3dc9742b921eb818f14fe3527e.JPG\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Vratimo se na pijanog \u010dovjeka i prednosti koje dobiva \u010dovjek-majmuna prilikom dekompozicije: <\/p>\n<p><\/p>\n<ul>\n<li>Kod je postao potpuno jasan na svakoj razini.<\/li>\n<li>Kod mogu pisati vi\u0161e programera istovremeno (svaki pi\u0161e zaseban element).<\/li>\n<li>Pojednostavljuje se automatsko testiranje - \u0161to je element jednostavniji, to ga je lak\u0161e testirati.<\/li>\n<li>Pojavljuje se kompozicionalnost koda - mo\u017eete zamijeniti <strong>DrinkUpOperation<\/strong> operaciju u kojoj pijanica prosipa teku\u0107inu ispod stola. Ili zamijeniti operaciju to\u010denja s operacijom u kojoj mije\u0161ate vino i vodu ili vodku i pivo. Ovisno o poslovnim zahtjevima, mo\u017eete u\u010diniti sve to, a da pritom ne dirate kod metode. <strong>Tippler.Act<\/strong>. <\/li>\n<li>Od ovih operacija mo\u017eete sastaviti prejedaju (koriste\u0107i samo <strong>TakeBitOperation<\/strong>), alkoholi\u010dara (koriste\u0107i samo <strong>DrinkUpOperation<\/strong> direktno iz boce) i zadovoljiti mnoge druge poslovne zahtjeve.<\/li>\n<\/ul>\n<p><\/p>\n<p><em>(Oh, \u010dini se da je ovo ve\u0107 OCP princip, i prekr\u0161io sam odgovornost ovog posta.) <\/em><\/p>\n<p><\/p>\n<p>I naravno, nedostaci: <\/p>\n<p><\/p>\n<ul>\n<li>Morat \u0107ete stvoriti vi\u0161e tipova. <\/li>\n<li>Pijanica \u0107e prvi put popiti nekoliko sati kasnije nego \u0161to bi mogao.<\/li>\n<\/ul>\n<p><\/p>\n<h2 id=\"opredelenie-2-edinaya-izmenchivost\">Definicija 2. Jedinstvena promjenjivost.<\/h2>\n<p><\/p>\n<p>Dozvolite gospodari! Klasa pijanice tako\u0111er ima jedinstvenu odgovornost \u2014 ona pije! I uop\u0107e, rije\u010d &#171;odgovornost&#187; je izrazito nejasan koncept. Netko je odgovoran za sudbinu \u010dovje\u010danstva, a netko je odgovoran za podizanje prevrnutih pingvina na polu.<\/p>\n<p><\/p>\n<p>Razmotrite dvije implementacije pi\u0107a. Prva, ranije navedena, sadr\u017ei tri klase \u2014 uliti, popiti i grickati.<\/p>\n<p><\/p>\n<p>Drugi je napisan metodologijom &#171;Naprijed i samo naprijed&#187; i sadr\u017ei svu logiku u metodi <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>Obje ove klase, s gledi\u0161ta vanjskog promatra\u010da, izgledaju potpuno identi\u010dno i imaju jedinstvenu odgovornost &#171;popiti&#187;. <\/p>\n<p><\/p>\n<p>Neugodno!<\/p>\n<p><\/p>\n<p>Tada zaronimo u internet i saznamo drugu definiciju SRP \u2014 Princip jedinstvene promjene (Single Changeability Principle).<\/p>\n<p><\/p>\n<p>SCP ka\u017ee da &#171;<strong>Modul ima samo jedan i jedini razlog za promjenu<\/strong>&#171;. Drugim rije\u010dima &#171;Odgovornost \u2014 to je razlog za promjenu&#187;. <\/p>\n<p><\/p>\n<p><em>(Izgleda da su momci koji su smislili prvotnu definiciju bili uvjereni u telepatske sposobnosti \u010dovjeka-majmuna)<\/em><\/p>\n<p><\/p>\n<p>Sada se sve sla\u017ee. Odvojeno mo\u017eemo mijenjati procese ulijevanja, pijenja i grickanja, a u samom pi\u0107u mo\u017eemo promijeniti samo redoslijed i sastav operacija, na primjer, premje\u0161tanjem grickalice ispred pijenja ili dodavanjem \u010ditanja toasta.<\/p>\n<p><\/p>\n<p>U pristupu &#171;Naprijed i samo naprijed&#187;, sve \u0161to se mo\u017ee promijeniti \u2014 mijenja se samo u metodi <strong>Act<\/strong>. To mo\u017ee biti \u010ditljivo i u\u010dinkovito kada je logike malo i rijetko se mijenja, ali \u010desto zavr\u0161ava stra\u0161nim metodama od 500 linija, s brojem if -ova ve\u0107im nego \u0161to je potrebno za pristup Rusije u NATO. <\/p>\n<p><\/p>\n<h2 id=\"opredelenie-3-lokalizaciya-izmeneniy\">Definicija 3. Lokalizacija promjena.<\/h2>\n<p><\/p>\n<p>Pijana osoba \u010desto ne razumije za\u0161to se probudila u tu\u0111em stanu, ili gdje joj je mobitel. Do\u0161lo je vrijeme da dodamo detaljno logiranje.<\/p>\n<p><\/p>\n<p>Zapo\u010dnimo logiranje s procesom ulijevanja:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">class PourOperation: IOperation{\n    PourOperation(ILogger log \/*....*\/){\/*...*\/}\n    \/\/...\n    void Do(){\n        _log.Log($\"Prije ulijevanja s {_hand} i {_bottle}\");\n        \/\/Poslovna logika ulijevanja ...\n        _log.Log($\"Nakon ulijevanja s {_hand} i {_bottle}\");\n    }\n}<\/code><\/pre>\n<p><\/p>\n<p>Inkapulirav\u0161i je u <strong>PourOperation<\/strong>, postupili smo mudro s obzirom na odgovornost i enkapsulaciju, ali imamo problem s principom promjenljivosti. Osim same operacije koja se mo\u017ee mijenjati, promjenljiva postaje i sama logika. Trebat \u0107emo podijeliti i stvoriti posebni logger za operaciju to\u010denja:<\/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    void Do(){\n        _log.LogBefore(_hand, _bottle);\n        try{\n             \/\/... poslovna logika\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>Pa\u017eljiv \u010ditatelj primijetit \u0107e da <strong>LogAfter<\/strong>, <strong>LogBefore<\/strong> i <strong>OnError<\/strong> tako\u0111er se mogu mijenjati pojedina\u010dno, a po analogiji s prethodnim postupcima \u0107e stvoriti tri klase: <strong>PourLoggerBefore<\/strong>, <strong>PourLoggerAfter<\/strong> i <strong>PourErrorLogger<\/strong>.<\/p>\n<p><\/p>\n<p>A s obzirom na to da postoje tri operacije to\u010denja, dobivamo devet klasa logiranja. Tako da cijeli sustav to\u010denja sastoji se od 14 (!!!) klasa.<\/p>\n<p><\/p>\n<p>Hipoteka? Jedva! \u010covjek-majmuna s dekompozicijskom granatom raspar\u010da 'to\u010ditelja' na bokal, \u010da\u0161u, operatore to\u010denja, servis za delivery vode, fizi\u010dki model sudara molekula, a sljede\u0107i kvartal \u0107e poku\u0161avati raspetljati ovisnosti bez globalnih varijabli. I vjerujte \u2014 ne\u0107e stati.<\/p>\n<p><\/p>\n<p>Na ovom mjestu mnogi dolaze do zaklju\u010dka da je SRP samo bajka iz ru\u017ei\u010dastih kraljevstava i odlaze vezati rezance&#8230;<\/p>\n<p><\/p>\n<p>\u2026 a da nikada ne saznaju o postojanju tre\u0107e definicije SRP: <\/p>\n<p><\/p>\n<p>&#171;Princip jedinstvene odgovornosti ka\u017ee da <strong>sli\u010dne stvari za promjenu trebaju biti pohranjene na jednom mjestu<\/strong>&#171;. ili \u201c<strong>Ono \u0161to se mijenja zajedno, treba biti pohranjeno na jednom mjestu<\/strong>\u201d<\/p>\n<p><\/p>\n<p>To jest, ako mijenjamo logiku operacije, trebali bismo to mijenjati na jednom mjestu.<\/p>\n<p><\/p>\n<p>To je vrlo va\u017ena to\u010dka \u2014 jer su sva obja\u0161njenja SRP-a, koja su bila ranije, govorila o tome da treba razbiti tipove dok se razbijaju, tj. postavljalo je &#171;gornje ograni\u010denje&#187; na veli\u010dinu objekta, a sada govorimo i o &#171;donjem ograni\u010denju&#187;. Drugim rije\u010dima, <strong>SRP ne samo da zahtijeva &#171;razbijanje dok se razbija&#187;, ve\u0107 i da se ne pretjeruje \u2014 &#171;ne razbiti povezane stvari&#187;<\/strong>. To je velika bitka Ockamove o\u0161trice s \u010dovjekom-majmunom!<\/p>\n<p>\n<img decoding=\"async\" alt=\"Jedinstveni odgovorni princip. Nije tako jednostavno kao \u0161to se \u010dini\" src=\"\/wp-content\/uploads\/2019\/06\/2e349a5b119a511d716341f3f6725844.JPG\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Sada bi to\u010ditelju trebalo biti lak\u0161e. Osim toga, \u0161to ne treba razdvajati logger IPourLogger na tri klase, tako\u0111er mo\u017eemo spojiti sve loggere u jedan tip:<\/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>I ako nam se doda \u010detvrti tip operacije, onda je logiranje ve\u0107 spremno. A kod samih operacija je \u010dist i oslobo\u0111en infrastrukturne buke.<\/p>\n<p><\/p>\n<p>U rezultatu imamo 5 klasa za rje\u0161avanje problema to\u010denja:<\/p>\n<p><\/p>\n<ul>\n<li>Operacija to\u010denja<\/li>\n<li>Operacija ispijanja<\/li>\n<li>Operacija grickanja<\/li>\n<li>Loger<\/li>\n<li>Facade to\u010denja<\/li>\n<\/ul>\n<p><\/p>\n<p>Svaka od njih odgovara isklju\u010divo za jednu funkcionalnost i ima jedan razlog za promjenu. Sva sli\u010dna pravila za promjenu su blizu jedni drugima. <\/p>\n<p>\n<b class=\"spoiler_title\">Primjer iz stvarnog \u017eivota<\/b><\/p>\n<p>Jednom smo radili servis za automatsku registraciju b2b klijenta. Pojavila se GOD-metoda sa 200 redaka takvog sadr\u017eaja:<\/p>\n<p><\/p>\n<ul>\n<li>Idi u 1C i otvori ra\u010dun<\/li>\n<li>S tim ra\u010dunom idi do modula za pla\u0107anje i otvori ga tamo<\/li>\n<li>Provjeri da ra\u010dun s takvim brojem nije ve\u0107 napravljen u glavnom <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/hr\/server\/dts-dronten\/\"   title=\"serveru\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"2485\">serveru<\/a><\/li>\n<li>Kreiraj novi ra\u010dun<\/li>\n<li>Rezultat registracije u modulu za pla\u0107anje i broj 1C dodaj u servis rezultata registracije<\/li>\n<li>Dodaj u ovu tabelu informacije o ra\u010dunu<\/li>\n<li>Kreiraj broj to\u010dke za ovog klijenta u servisu to\u010daka. Prenesi u taj servis broj ra\u010duna 1C.<\/li>\n<\/ul>\n<p><\/p>\n<p>I bilo je u ovom popisu jo\u0161 oko 10 poslovnih operacija s stra\u0161nom povezano\u0161\u0107u. Objekt ra\u010duna bio je potreban gotovo svima. Identifikator to\u010dke i ime klijenta bili su potrebni u polovini poziva.<\/p>\n<p><\/p>\n<p>Nakon sat vremena refaktorizacije, uspjeli smo odvojiti infrastrukturni kod i neke nijanse rada s ra\u010dunom u posebne metode\/klase. God metoda se olak\u0161ala, ali ostalo je 100 redaka koda koji se nikako nisu \u017eeljeli rasplesti. <\/p>\n<p><\/p>\n<p>Tek nakon nekoliko dana do\u0161ao je uvid da je su\u0161tina ove &#171;olak\u0161ane&#187; metode \u2014 upravo poslovni algoritam. I da je izvorni opis T\u0417 bio prili\u010dno slo\u017een. I upravo \u0107e poku\u0161aj razbijanja ovog metoda na dijelove biti kr\u0161enje SRP-a, a ne obrnuto. <\/p>\n<p><\/p>\n<h2 id=\"formalizm\">Formalizam.<\/h2>\n<p><\/p>\n<p>Do\u0161lo je vrijeme da ostavimo na\u0161u to\u010dionicu na miru. Obri\u0161i suze \u2014 sigurno \u0107emo se ponovno vratiti njemu nekada. A sada formalizirajmo znanje iz ovog \u010dlanka. <\/p>\n<p><\/p>\n<h4 id=\"formalizm-1-opredelenie-srp\">Formalizam 1. Definicija SRP<\/h4>\n<p><\/p>\n<ol>\n<li>Dijelite elemente tako da svaki od njih bude odgovoran za ne\u0161to jedno.<\/li>\n<li>Odgovornost se obja\u0161njava kao 'povod za izmjenu'. Drugim rije\u010dima, svaki element ima samo jedan povod za izmjenu, u terminima poslovne logike.<\/li>\n<li>Potencijalne promjene poslovne logike trebaju biti lokalizirane. Promjenjivi sinkronizirani elementi trebaju biti blizu.<\/li>\n<\/ol>\n<p><\/p>\n<h4 id=\"formalizm-2-neobhodimye-kriterii-samoproverki\">Formalizam 2. Potrebni kriteriji samoprovjere.<\/h4>\n<p><\/p>\n<p>Nisam se susreo s dovoljnim kriterijima za provedbu SRP. No postoje potrebni uvjeti:<\/p>\n<p><\/p>\n<p>1) Postavite si pitanje \u2014 \u0161to radi ova klasa\/metoda\/modul\/servis. Na njega trebate odgovoriti jednostavnom definicijom. (hvala <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\">obja\u0161njenja<\/b><\/p>\n<p>U svakom slu\u010daju, ponekad je izuzetno te\u0161ko prona\u0107i jednostavnu definiciju. <\/p>\n<p><\/p>\n<p>2) Ispravak odre\u0111enog buga ili dodavanje nove funkcionalnosti utje\u010de na minimalan broj datoteka\/klasa. U idealnom slu\u010daju \u2014 jednu. <\/p>\n<p>\n<b class=\"spoiler_title\">obja\u0161njenja<\/b><\/p>\n<p>S obzirom na to da je odgovornost (za funkcionalnost ili bug) inkapsulirana u jednoj datoteci\/klasi, to\u010dno znate gdje potra\u017eiti i \u0161to promijeniti. Na primjer: funkcionalnost promjene izlaza logiranja operacija zahtijeva promjenu samo loggera. Nije potrebno pretra\u017eivati ostatak koda. <\/p>\n<p><\/p>\n<p>Drugi primjer \u2014 dodavanje novog UI kontrola, sli\u010dnog prethodnima. Ako vas to natjera da dodate 10 razli\u010ditih entiteta i 15 razli\u010ditih konvertera \u2014 \u010dini se da ste \"preoptere\u0107eni\".<\/p>\n<p><\/p>\n<p>3) Ako nekoliko programera radi na razli\u010ditim funkcionalnostima va\u0161eg projekta, vjerojatnost sukoba pri spajanju, odnosno vjerojatnost da \u0107e istu datoteku\/klasu izmijeniti nekoliko programera istovremeno \u2014 minimalna je.<\/p>\n<p>\n<b class=\"spoiler_title\">obja\u0161njenja<\/b><\/p>\n<p>Ako prilikom dodavanja nove operacije 'Ispustiti vodku ispod stola' trebate dodirnuti logger, operaciju ispijanja i izlijevanja \u2014 izgleda da su odgovornosti nerazmjerno raspodijeljene. Naravno, to nije uvijek mogu\u0107e, ali treba se truditi smanjiti ovaj pokazatelj. <\/p>\n<p><\/p>\n<p>4) Na poja\u0161njavaju\u0107e pitanje o poslovnoj logici (od programera ili menad\u017eera) ulazite strogo u jednu klasu\/datoteku i dobivate informacije samo odatle.<\/p>\n<p>\n<b class=\"spoiler_title\">obja\u0161njenja<\/b><\/p>\n<p>Funkcionalnosti, pravila ili algoritmi kompaktno su napisani svaki na jednom mjestu, a ne razbacani zastavicama po cijelom kodu.<\/p>\n<p><\/p>\n<p>5) Ime je jasno.<\/p>\n<p>\n<b class=\"spoiler_title\">obja\u0161njenja<\/b><\/p>\n<p>Na\u0161a klasa ili metoda odgovorna je za ne\u0161to jedno, i odgovornost je odra\u017eena u njenom nazivu.<\/p>\n<p><\/p>\n<p>AllManagersManagerService \u2014 vjerojatno, Bog-klasa.<br \/>\nLocalPayment \u2014 vjerojatno ne. <\/p>\n<p><\/p>\n<h4 id=\"formalizm-3-metodika-razrabotki-okkama-first\">Formalizam 3. Metodologija razvoja 'Ockham-prvo'.<\/h4>\n<p><\/p>\n<p>Na po\u010detku projektiranja, \u010dovjek-majmuna ne zna i ne osje\u0107a sve nijanse rije\u0161enog zadatka i mo\u017ee napraviti gre\u0161ku. Gre\u0161ke mogu nastati na razli\u010dite na\u010dine:<\/p>\n<p><\/p>\n<ul>\n<li>Prevelike objekte napraviti spajanjem razli\u010ditih odgovornosti.<\/li>\n<li>Razlo\u017eiti jedinstvenu odgovornost na mnogo razli\u010ditih tipova.<\/li>\n<li>Pogre\u0161no definirati granice odgovornosti.<\/li>\n<\/ul>\n<p><\/p>\n<p>Va\u017eno je zapamtiti pravilo: 'bolje je grije\u0161iti u ve\u0107u stranu', ili 'ako niste sigurni \u2014 ne komplicirajte'. Na primjer, ako va\u0161a klasa obuhva\u0107a dvije odgovornosti \u2014 ona je i dalje jasna i mo\u017ee se podijeliti na dva s minimalnom promjenom klijentskog koda. Sastavljanje \u010da\u0161e od komadi\u0107a stakla je, u pravilu, te\u017ee zbog razbacanog konteksta kroz nekoliko datoteka i nedostatka potrebnih ovisnosti u klijentskom kodu. <\/p>\n<p><\/p>\n<h2 id=\"pora-zakruglyatsya\">Vrijeme je da se zaklju\u010di.<\/h2>\n<p><\/p>\n<p>Primjena SRP-a ne ograni\u010dava se na OOP i SOLID. Primjenjuje se na metode, funkcije, klase, module, mikrousluge i servise. Primjenjuje se i na \"figaks-figaks-i-u-produkciji\" i \"raketna znanost\" razvoj, \u010dine\u0107i svijet malo boljim svuda. Ako dobro razmislimo, to je vjerojatno temeljni princip cijelog in\u017eenjerstva. Strojogradnja, sustavi upravljanja, pa i svi slo\u017eeni sustavi \u2014 grade se od komponenata, a \"nedovoljno razdvajanje\" li\u0161ava konstruatore fleksibilnosti, \"prekomjerno razdvajanje\" \u2014 u\u010dinkovitosti, dok pogre\u0161ne granice oduzimaju razboritost i du\u0161evni mir. <\/p>\n<p>\n<img decoding=\"async\" alt=\"Jedinstveni odgovorni princip. Nije tako jednostavno kao \u0161to se \u010dini\" src=\"\/wp-content\/uploads\/2019\/06\/b70fb2b0b87cf90d41462263e839902b.JPG\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>SRP nije izumljen prirodom i nije dio to\u010dne znanosti. Izra\u017eava se iz na\u0161ih biolo\u0161kih i psiholo\u0161kih ograni\u010denja. To je samo na\u010din kontrole i razvoja slo\u017eenih sustava koriste\u0107i ljudski um. Obja\u0161njava nam kako dekomponirati sustav. Izvorna formulacija zahtijevala je odre\u0111enu vje\u0161tinu telepatije, ali se nadam da je ovaj \u010dlanak donekle raspucao dimnu zavjesu.<\/p>\n<p>Izvor: <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.4 - 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\/hr\/blog\/news\/single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"hr_HR\" \/>\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\/hr\/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. Nije tako jednostavno kao \u0161to se \u010dini | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/hr\/blog\/news\/single-responsibility-principle-ne-takoj-prostoj-kak-kazhetsya","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"hr_HR","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\/hr\/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\/hr\/wp-json\/wp\/v2\/posts\/34828","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/comments?post=34828"}],"version-history":[{"count":1,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts\/34828\/revisions"}],"predecessor-version":[{"id":159767,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts\/34828\/revisions\/159767"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/media\/26229"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/media?parent=34828"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/categories?post=34828"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/tags?post=34828"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}