Kanuni ya Wajibu Mmoja. Sio rahisi kama inavyoonekana

Kanuni ya Wajibu Mmoja. Sio rahisi kama inavyoonekana Kanuni ya uwajibikaji mmoja, pia inajulikana kama kanuni ya jukumu moja,
aka kanuni ya kutofautisha kwa usawa - mtu anayeteleza sana kuelewa na swali la wasiwasi kama hilo kwenye mahojiano ya programu.

Ujuzi wangu wa kwanza wa dhati na kanuni hii ulifanyika mwanzoni mwa mwaka wa kwanza, wakati wale wachanga na wa kijani walipelekwa msituni kufanya wanafunzi kutoka kwa mabuu - wanafunzi wa kweli.

Katika msitu, tuligawanywa katika vikundi vya watu 8-9 kila mmoja na tukawa na mashindano - ni kikundi gani kingekunywa chupa ya vodka haraka sana, mradi tu mtu wa kwanza kutoka kwa kikundi amimina vodka kwenye glasi, wa pili anakunywa, na wa tatu ana vitafunio. Kitengo ambacho kimekamilisha operesheni yake husogea hadi mwisho wa foleni ya kikundi.

Kesi ambapo saizi ya foleni ilikuwa nyingi ya tatu ilikuwa utekelezaji mzuri wa SRP.

Ufafanuzi 1. Wajibu mmoja.

Ufafanuzi rasmi wa Kanuni ya Uwajibikaji Mmoja (SRP) inasema kwamba kila chombo kina wajibu na sababu yake ya kuwepo, na kina jukumu moja tu.

Fikiria kitu "Mnywaji" (Mtoaji).
Ili kutekeleza kanuni ya SRP, tutagawanya majukumu katika tatu:

  • Mmoja anamimina (Uendeshaji wa kumwaga)
  • Kinywaji kimoja (DrinkUpOperation)
  • Mmoja ana vitafunio (TakeBiteOperation)

Kila mmoja wa washiriki katika mchakato anajibika kwa sehemu moja ya mchakato, yaani, ana jukumu moja la atomiki - kunywa, kumwaga au vitafunio.

Shimo la kunywa, kwa upande wake, ni facade ya shughuli hizi:

сlass Tippler {
    //...
    void Act(){
        _pourOperation.Do() // Π½Π°Π»ΠΈΡ‚ΡŒ
        _drinkUpOperation.Do() // Π²Ρ‹ΠΏΠΈΡ‚ΡŒ
        _takeBiteOperation.Do() // Π·Π°ΠΊΡƒΡΠΈΡ‚ΡŒ
    }
}

Kanuni ya Wajibu Mmoja. Sio rahisi kama inavyoonekana

Kwa nini?

Mpangaji wa programu ya binadamu huandika kanuni kwa ajili ya nyani-mtu, na nyani-mtu hana makini, mjinga na daima ana haraka. Anaweza kushikilia na kuelewa kuhusu maneno 3 - 7 kwa wakati mmoja.
Katika kesi ya mlevi, kuna maneno matatu kati ya haya. Hata hivyo, ikiwa tutaandika kanuni na karatasi moja, basi itakuwa na mikono, glasi, mapigano na mabishano yasiyo na mwisho kuhusu siasa. Na hii yote itakuwa katika mwili wa njia moja. Nina hakika umeona nambari kama hiyo katika mazoezi yako. Sio mtihani wa kibinadamu zaidi kwa psyche.

Kwa upande mwingine, nyani ameundwa kuiga vitu vya ulimwengu halisi kichwani mwake. Katika mawazo yake, anaweza kuwasukuma pamoja, kukusanya vitu vipya kutoka kwao, na kuwatenganisha kwa njia ile ile. Fikiria gari la zamani la mfano. Kwa mawazo yako, unaweza kufungua mlango, kufuta trim ya mlango na kuona huko taratibu za kuinua dirisha, ndani ambayo kutakuwa na gia. Lakini huwezi kuona vipengele vyote vya mashine kwa wakati mmoja, katika "orodha" moja. Angalau "mtu wa tumbili" hawezi.

Kwa hivyo, waandaaji wa programu za wanadamu hutengana mifumo ngumu kuwa seti ya vitu visivyo ngumu na vya kufanya kazi. Hata hivyo, inaweza kuharibiwa kwa njia tofauti: katika magari mengi ya zamani, duct ya hewa huingia kwenye mlango, na katika magari ya kisasa, kushindwa kwa umeme wa kufuli huzuia injini kuanza, ambayo inaweza kuwa tatizo wakati wa matengenezo.

Sasa, SRP ni kanuni inayoelezea JINSI ya kutengana, ambayo ni, wapi kuchora mstari wa kugawanya.

Anasema kwamba ni muhimu kutengana kulingana na kanuni ya mgawanyiko wa "wajibu," yaani, kulingana na kazi za vitu fulani.

Kanuni ya Wajibu Mmoja. Sio rahisi kama inavyoonekana

Wacha turudi kwenye kunywa na faida ambazo mtu wa tumbili hupokea wakati wa mtengano:

  • Kanuni imekuwa wazi sana katika kila ngazi
  • Nambari inaweza kuandikwa na watengeneza programu kadhaa mara moja (kila mmoja anaandika kipengee tofauti)
  • Upimaji wa kiotomatiki umerahisishwa - rahisi zaidi kipengele, ni rahisi zaidi kupima
  • Muundo wa msimbo unaonekana - unaweza kuchukua nafasi DrinkUpOperation kwa operesheni ambayo mlevi humwaga kioevu chini ya meza. Au ubadilishe operesheni ya kumwaga na operesheni ambayo unachanganya divai na maji au vodka na bia. Kulingana na mahitaji ya biashara, unaweza kufanya kila kitu bila kugusa msimbo wa mbinu Sheria ya Tippler.
  • Kutoka kwa shughuli hizi unaweza kukunja mlafi (kwa kutumia tu TakeBitOperation), Pombe (kwa kutumia tu DrinkUpOperation moja kwa moja kutoka kwenye chupa) na kukidhi mahitaji mengine mengi ya biashara.

(Lo, inaonekana hii tayari ni kanuni ya OCP, na nilikiuka wajibu wa chapisho hili)

Na, kwa kweli, hasara:

  • Itabidi tuunde aina zaidi.
  • Mlevi hunywa kwa mara ya kwanza saa chache baadaye kuliko vile angeweza kunywa.

Ufafanuzi 2. Tofauti ya umoja.

Niruhusu, mabwana! Darasa la kunywa pia lina jukumu moja - linakunywa! Na kwa ujumla, neno "wajibu" ni dhana isiyoeleweka sana. Mtu anawajibika kwa hatima ya ubinadamu, na mtu ana jukumu la kuinua penguins ambazo zilipinduliwa kwenye nguzo.

Hebu fikiria utekelezaji mbili za mnywaji. Ya kwanza, iliyotajwa hapo juu, ina madarasa matatu - kumwaga, kunywa na vitafunio.

Ya pili imeandikwa kupitia mbinu ya "Mbele na Mbele Pekee" na ina mantiki yote katika mbinu Sheria:

//НС Ρ‚Ρ€Π°Ρ‚ΡŒΡ‚Π΅ врСмя  Π½Π° ΠΈΠ·ΡƒΡ‡Π΅Π½ΠΈΠ΅ этого класса. Π›ΡƒΡ‡ΡˆΠ΅ ΡΡŠΠ΅ΡˆΡŒΡ‚Π΅ ΠΏΠ΅Ρ‡Π΅Π½ΡŒΠΊΡƒ
сlass BrutTippler {
   //...
   void Act(){
        // Π½Π°Π»ΠΈΠ²Π°Π΅ΠΌ
    if(!_hand.TryDischarge(from:_bottle, to:_glass, size:_glass.Capacity))
        throw new OverdrunkException();

    // Π²Ρ‹ΠΏΠΈΠ²Π°Π΅ΠΌ
    if(!_hand.TryDrink(from: _glass,  size: _glass.Capacity))
        throw new OverdrunkException();

    //ЗакусываСм
    for(int i = 0; i< 3; i++){
        var food = _foodStore.TakeOrDefault();
        if(food==null)
            throw new FoodIsOverException();

        _hand.TryEat(food);
    }
   }
}

Madarasa haya yote mawili, kutoka kwa mtazamo wa mwangalizi wa nje, yanaonekana sawa na kushiriki jukumu sawa la "kunywa".

Mkanganyiko!

Kisha tunaingia mtandaoni na kupata ufafanuzi mwingine wa SRP - Kanuni ya Kubadilika Moja.

SCP inasema "Moduli ina sababu moja tu ya kubadilika". Hiyo ni, "Wajibu ni sababu ya mabadiliko."

(Inaonekana kwamba wavulana ambao walikuja na ufafanuzi wa asili walikuwa na ujasiri katika uwezo wa telepathic wa mtu wa ape)

Sasa kila kitu kinaanguka mahali. Kwa kando, tunaweza kubadilisha taratibu za kumwaga, kunywa na vitafunio, lakini katika mnywaji yenyewe tunaweza kubadilisha tu mlolongo na muundo wa shughuli, kwa mfano, kwa kusonga vitafunio kabla ya kunywa au kuongeza usomaji wa toast.

Katika njia ya "Mbele na Mbele tu", kila kitu kinachoweza kubadilishwa kinabadilishwa tu kwa njia Sheria. Hili linaweza kusomeka na kufaa kunapokuwa na mantiki kidogo na mara chache hubadilika, lakini mara nyingi huishia katika mbinu mbaya za mistari 500 kila moja, ikiwa na taarifa nyingi zaidi kuliko inavyohitajika kwa Urusi kujiunga na NATO.

Ufafanuzi 3. Ujanibishaji wa mabadiliko.

Wanywaji mara nyingi hawaelewi kwa nini waliamka katika ghorofa ya mtu mwingine, au wapi simu zao za mkononi. Ni wakati wa kuongeza kumbukumbu za kina.

Wacha tuanze kukata miti na mchakato wa kumwaga:

class PourOperation: IOperation{
    PourOperation(ILogger log /*....*/){/*...*/}
    //...
    void Do(){
        _log.Log($"Before pour with {_hand} and {_bottle}");
        //Pour business logic ...
        _log.Log($"After pour with {_hand} and {_bottle}");
    }
}

Kwa kuiingiza ndani Uendeshaji wa kumwaga, tulifanya kwa busara kutoka kwa mtazamo wa wajibu na encapsulation, lakini sasa tunachanganyikiwa na kanuni ya kutofautiana. Mbali na operesheni yenyewe, ambayo inaweza kubadilika, magogo yenyewe pia yanabadilika. Utalazimika kutenganisha na kuunda logger maalum kwa operesheni ya kumwaga:

interface IPourLogger{
    void LogBefore(IHand, IBottle){}
    void LogAfter(IHand, IBottle){}
    void OnError(IHand, IBottle, Exception){}
}

class PourOperation: IOperation{
    PourOperation(IPourLogger log /*....*/){/*...*/}
    //...
    void Do(){
        _log.LogBefore(_hand, _bottle);
        try{
             //... business logic
             _log.LogAfter(_hand, _bottle");
        }
        catch(exception e){
            _log.OnError(_hand, _bottle, e)
        }
    }
}

Msomaji makini atagundua hilo LogAfter, IngiaKabla ΠΈ OneError inaweza pia kubadilishwa kibinafsi, na, kwa kulinganisha na hatua za awali, itaunda madarasa matatu: PourLoggerKabla, PourLoggerAfter ΠΈ PourErrorLogger.

Na kukumbuka kuwa kuna shughuli tatu kwa mnywaji, tunapata madarasa tisa ya ukataji miti. Matokeo yake, mzunguko mzima wa kunywa unajumuisha madarasa 14 (!!!).

Hyperbola? Vigumu! Mtu wa tumbili aliye na grenade ya mtengano atagawanya "mwagaji" kuwa decanter, glasi, waendeshaji wa kumwaga, huduma ya usambazaji wa maji, mfano wa mgongano wa molekuli, na kwa robo inayofuata atajaribu kusuluhisha utegemezi bila. vigezo vya kimataifa. Na niniamini, hataacha.

Ni wakati huu ambapo wengi hufikia hitimisho kwamba SRP ni hadithi za hadithi kutoka kwa falme za waridi, na kwenda kucheza noodles...

... bila hata kujifunza juu ya uwepo wa ufafanuzi wa tatu wa Srp:

β€œKanuni ya Uwajibikaji Mmoja inasema kwamba mambo ambayo yanafanana na mabadiliko yanapaswa kuhifadhiwa mahali pamoja". au"Ni mabadiliko gani pamoja yanapaswa kuwekwa mahali pamoja"

Hiyo ni, ikiwa tunabadilisha ukataji wa operesheni, basi lazima tuibadilishe mahali pamoja.

Hili ni jambo muhimu sana - kwa kuwa maelezo yote ya SRP ambayo yalikuwa hapo juu yalisema kwamba ilikuwa ni lazima kuponda aina wakati zinapondwa, yaani, waliweka "kikomo cha juu" kwa ukubwa wa kitu, na sasa. tayari tunazungumza juu ya "kikomo cha chini" . Kwa maneno mengine, SRP haihitaji tu "kuponda wakati wa kuponda", lakini pia sio kuipindua - "usivunje vitu vilivyounganishwa". Hii ndiyo vita kuu kati ya wembe wa Occam na nyani!

Kanuni ya Wajibu Mmoja. Sio rahisi kama inavyoonekana

Sasa mnywaji anapaswa kujisikia vizuri. Kwa kuongeza ukweli kwamba hakuna haja ya kugawanya logger ya IPourLogger katika madarasa matatu, tunaweza pia kuchanganya wakataji miti wote katika aina moja:

class OperationLogger{
    public OperationLogger(string operationName){/*..*/}
    public void LogBefore(object[] args){/*...*/}       
    public void LogAfter(object[] args){/*..*/}
    public void LogError(object[] args, exception e){/*..*/}
}

Na ikiwa tunaongeza aina ya nne ya operesheni, basi ukataji wa miti kwa hiyo tayari uko tayari. Na kanuni za shughuli zenyewe ni safi na hazina kelele za miundombinu.

Kama matokeo, tuna madarasa 5 ya kutatua shida ya unywaji:

  • Operesheni ya kumwaga
  • Operesheni ya kunywa
  • Uendeshaji wa Jamming
  • Mkata miti
  • Kinywaji facade

Kila mmoja wao anajibika madhubuti kwa utendaji mmoja na ana sababu moja ya mabadiliko. Sheria zote zinazofanana na mabadiliko ziko karibu.

Mfano wa maisha halisi

Wakati mmoja tuliandika huduma ya kusajili kiotomatiki mteja wa b2b. Na njia ya MUNGU ilionekana kwa mistari 200 ya yaliyomo sawa:

  • Nenda kwa 1C na uunde akaunti
  • Ukiwa na akaunti hii, nenda kwenye sehemu ya malipo na uunde hapo
  • Hakikisha kuwa akaunti iliyo na akaunti kama hiyo haijaundwa kwenye seva kuu
  • Fungua akaunti mpya
  • Ongeza matokeo ya usajili katika moduli ya malipo na nambari ya 1c kwenye huduma ya matokeo ya usajili
  • Ongeza maelezo ya akaunti kwenye jedwali hili
  • Unda nambari ya uhakika kwa mteja huyu katika huduma ya uhakika. Tuma nambari yako ya akaunti ya 1c kwa huduma hii.

Na kulikuwa na takriban shughuli 10 zaidi za biashara kwenye orodha hii zenye muunganisho mbaya. Takriban kila mtu alihitaji kipengee cha akaunti. Kitambulisho cha uhakika na jina la mteja zilihitajika katika nusu ya simu.

Baada ya saa moja ya kurekebisha tena, tuliweza kutenganisha msimbo wa miundombinu na baadhi ya nuances ya kufanya kazi na akaunti katika mbinu/madarasa tofauti. Mbinu ya Mungu ilifanya iwe rahisi, lakini kulikuwa na mistari 100 ya msimbo iliyosalia ambayo haikutaka tu kung'olewa.

Tu baada ya siku chache ikawa wazi kuwa kiini cha njia hii "nyepesi" ni algorithm ya biashara. Na kwamba maelezo ya asili ya maelezo ya kiufundi yalikuwa magumu sana. Na ni jaribio la kuvunja njia hii vipande vipande ambavyo vitakiuka SRP, na si kinyume chake.

Urasmi.

Ni wakati wa kuwaacha walevi wetu peke yao. Kausha machozi yako - hakika tutarudi kwake siku moja. Sasa hebu tufanye ujuzi kutoka kwa makala hii.

Urasmi 1. Ufafanuzi wa SRP

  1. Tenganisha vipengele ili kila mmoja wao awajibike kwa jambo moja.
  2. Wajibu unasimama kwa "sababu ya kubadilika." Hiyo ni, kila kipengele kina sababu moja tu ya mabadiliko, katika suala la mantiki ya biashara.
  3. Mabadiliko yanayowezekana kwa mantiki ya biashara. lazima iwe ya ndani. Vipengele vinavyobadilika kwa usawa lazima viwe karibu.

Urasmi 2. Vigezo vya lazima vya kujipima.

Sijaona vigezo vya kutosha vya kutimiza SRP. Lakini kuna masharti muhimu:

1) Jiulize darasa/mbinu/moduli/huduma hii inafanya nini. lazima ujibu kwa ufafanuzi rahisi. ( Asante Brightori )

maelezo

Hata hivyo, wakati mwingine ni vigumu sana kupata ufafanuzi rahisi

2) Kurekebisha hitilafu au kuongeza kipengele kipya huathiri idadi ya chini kabisa ya faili/madarasa. Bora - moja.

maelezo

Kwa kuwa uwajibikaji (kwa kipengele au mdudu) umewekwa katika faili/darasa moja, unajua hasa mahali pa kuangalia na nini cha kuhariri. Kwa mfano: kipengele cha kubadilisha pato la shughuli za ukataji miti itahitaji kubadilisha tu logger. Hakuna haja ya kukimbia kwa njia iliyobaki ya nambari.

Mfano mwingine ni kuongeza kidhibiti kipya cha UI, sawa na kilichotangulia. Iwapo hii inakulazimisha kuongeza huluki 10 tofauti na vigeuzi 15 tofauti, inaonekana kama unaitumia kupita kiasi.

3) Ikiwa watengenezaji kadhaa wanafanya kazi kwenye vipengele tofauti vya mradi wako, basi uwezekano wa mgongano wa kuunganisha, yaani, uwezekano kwamba faili / darasa sawa litabadilishwa na watengenezaji kadhaa kwa wakati mmoja, ni ndogo.

maelezo

Ikiwa, wakati wa kuongeza operesheni mpya "Mimina vodka chini ya meza", unahitaji kuathiri logger, uendeshaji wa kunywa na kumwaga, basi inaonekana kama majukumu yamegawanywa kwa upotovu. Bila shaka, hii haiwezekani kila wakati, lakini tunapaswa kujaribu kupunguza takwimu hii.

4) Unapoulizwa swali la kufafanua kuhusu mantiki ya biashara (kutoka kwa msanidi programu au msimamizi), unaingia katika darasa/faili moja na kupokea taarifa kutoka hapo pekee.

maelezo

Vipengele, sheria au algoriti zimeandikwa kwa kubana, kila moja katika sehemu moja, na sio kutawanywa na bendera katika nafasi ya msimbo.

5) Jina ni wazi.

maelezo

Darasa letu au njia inawajibika kwa jambo moja, na jukumu linaonyeshwa kwa jina lake

AllManagersManagerService - uwezekano mkubwa ni darasa la Mungu
Malipo ya Ndani - labda sivyo

Urasimi 3. Mbinu ya maendeleo ya Occam-kwanza.

Mwanzoni mwa muundo, mtu wa tumbili hajui na hahisi hila zote za shida kutatuliwa na anaweza kufanya makosa. Unaweza kufanya makosa kwa njia tofauti:

  • Fanya vitu vikubwa sana kwa kuunganisha majukumu tofauti
  • Kuunda upya kwa kugawanya jukumu moja katika aina nyingi tofauti
  • Eleza kwa usahihi mipaka ya wajibu

Ni muhimu kukumbuka sheria: "ni bora kufanya kosa kubwa," au "ikiwa huna uhakika, usiigawanye." Ikiwa, kwa mfano, darasa lako lina majukumu mawili, basi bado linaeleweka na linaweza kugawanywa katika mbili na mabadiliko madogo kwa msimbo wa mteja. Kukusanya glasi kutoka kwa vipande vya glasi kawaida ni ngumu zaidi kwa sababu ya muktadha kuenea kwenye faili kadhaa na ukosefu wa vitegemezi muhimu katika nambari ya mteja.

Ni wakati wa kuiita siku

Upeo wa SRP hauzuiliwi kwa OOP na SOLID. Inatumika kwa mbinu, kazi, madarasa, modules, microservices na huduma. Inatumika kwa maendeleo ya "figax-figax-and-prod" na "roketi-sayansi", na kuifanya dunia kuwa bora kidogo kila mahali. Ikiwa unafikiri juu yake, hii ni karibu kanuni ya msingi ya uhandisi wote. Uhandisi wa mitambo, mifumo ya udhibiti, na kwa kweli mifumo yote changamano imejengwa kutoka kwa vipengele, na "upungufu" huwanyima wabunifu kubadilika, "kugawanyika zaidi" huwanyima wabunifu wa ufanisi, na mipaka isiyo sahihi inawanyima sababu na amani ya akili.

Kanuni ya Wajibu Mmoja. Sio rahisi kama inavyoonekana

SRP haijavumbuliwa kwa asili na sio sehemu ya sayansi halisi. Inatoka nje ya mapungufu yetu ya kibayolojia na kisaikolojia.Ni njia tu ya kudhibiti na kuendeleza mifumo changamano kwa kutumia ubongo wa nyani. Anatuambia jinsi ya kuoza mfumo. Uundaji asili ulihitaji kiasi cha kutosha cha telepathy, lakini natumai nakala hii itaondoa baadhi ya skrini ya moshi.

Chanzo: mapenzi.com

Kuongeza maoni