Egwyddor Cyfrifoldeb Sengl. Ddim mor syml ag y mae'n ymddangos

Egwyddor Cyfrifoldeb Sengl. Ddim mor syml ag y mae'n ymddangos Egwyddor cyfrifoldeb sengl, a elwir hefyd yn egwyddor cyfrifoldeb sengl,
aka egwyddor amrywioldeb unffurf - boi hynod o llithrig i'w ddeall a chwestiwn mor nerfus mewn cyfweliad rhaglennydd.

Fy adnabyddiaeth ddifrifol gyntaf o'r egwyddor hon a gymerodd le yn nechreu y flwyddyn gyntaf, pryd yr aethpwyd â'r rhai ieuainc a gwyrddion i'r goedwig i wneyd myfyrwyr allan o larfâu — efrydwyr gwirioneddol.

Yn y goedwig, cawsom ein rhannu'n grwpiau o 8-9 o bobl yr un a chawsom gystadleuaeth - pa grŵp fyddai'n yfed potel o fodca gyflymaf, ar yr amod bod y person cyntaf o'r grŵp yn arllwys fodca i mewn i wydr, a'r ail yn ei yfed, a'r trydydd yn cael byrbryd. Mae'r uned sydd wedi cwblhau ei gweithrediad yn symud i ddiwedd ciw y grŵp.

Roedd yr achos lle'r oedd maint y ciw yn lluosrif o dri yn weithrediad da o SRP.

Diffiniad 1. Cyfrifoldeb sengl.

Mae diffiniad swyddogol yr Egwyddor Cyfrifoldeb Sengl (SRP) yn nodi bod gan bob endid ei gyfrifoldeb a’i reswm ei hun dros fodolaeth, a dim ond un cyfrifoldeb sydd ganddo.

Ystyriwch y gwrthrych “Yfwr” (Tippler).
Er mwyn gweithredu’r egwyddor SRP, byddwn yn rhannu’r cyfrifoldebau yn dri:

  • Un yn arllwys (Arllwysiad)
  • Un diodydd (YfedUpOperation)
  • Mae un yn cael byrbryd (Gweithred TakeBite)

Mae pob un o'r cyfranogwyr yn y broses yn gyfrifol am un elfen o'r broses, hynny yw, mae ganddo un cyfrifoldeb atomig - yfed, arllwys neu fyrbryd.

Mae'r twll yfed, yn ei dro, yn ffasâd ar gyfer y gweithrediadau hyn:

сlass Tippler {
    //...
    void Act(){
        _pourOperation.Do() // налить
        _drinkUpOperation.Do() // выпить
        _takeBiteOperation.Do() // закусить
    }
}

Egwyddor Cyfrifoldeb Sengl. Ddim mor syml ag y mae'n ymddangos

Pam?

Mae'r rhaglennydd dynol yn ysgrifennu cod ar gyfer yr epa-ddyn, ac mae'r epa-ddyn yn ddisylw, yn dwp a bob amser ar frys. Gall ddal a deall tua 3 - 7 tymor ar yr un pryd.
Yn achos meddwyn, mae tri o'r termau hyn. Fodd bynnag, os byddwn yn ysgrifennu'r cod gydag un ddalen, yna bydd yn cynnwys dwylo, sbectol, ymladd a dadleuon diddiwedd am wleidyddiaeth. A bydd hyn oll yng nghorff un dull. Rwy'n siŵr eich bod wedi gweld cod o'r fath yn eich practis. Nid y prawf mwyaf trugarog ar gyfer y seice.

Ar y llaw arall, mae'r dyn epa wedi'i gynllunio i efelychu gwrthrychau byd go iawn yn ei ben. Yn ei ddychymyg, gall eu gwthio ynghyd, cydosod gwrthrychau newydd ohonynt, a'u dadosod yn yr un modd. Dychmygwch hen gar model. Yn eich dychymyg, gallwch chi agor y drws, dadsgriwio ymyl y drws a gweld yno fecanweithiau lifft y ffenestr, a bydd gerau y tu mewn iddynt. Ond ni allwch weld holl gydrannau'r peiriant ar yr un pryd, mewn un "rhestr". O leiaf ni all y “dyn mwnci”.

Felly, mae rhaglenwyr dynol yn dadelfennu mecanweithiau cymhleth yn set o elfennau llai cymhleth a gweithredol. Fodd bynnag, gellir ei ddadelfennu mewn gwahanol ffyrdd: mewn llawer o hen geir, mae'r ddwythell aer yn mynd i mewn i'r drws, ac mewn ceir modern, mae methiant yn y clo electroneg yn atal yr injan rhag cychwyn, a all fod yn broblem yn ystod atgyweiriadau.

Nawr, Mae SRP yn egwyddor sy'n esbonio SUT i ddadelfennu, hynny yw, ble i dynnu'r llinell rannu.

Dywed fod yn angenrheidiol dadelfenu yn ol yr egwyddor o raniad "cyfrifoldeb," hyny yw, yn ol gorchwylion rhai gwrthddrychau.

Egwyddor Cyfrifoldeb Sengl. Ddim mor syml ag y mae'n ymddangos

Gadewch i ni ddychwelyd i yfed a'r manteision y mae'r dyn mwnci yn eu derbyn yn ystod dadelfennu:

  • Mae'r cod wedi dod yn hynod glir ar bob lefel
  • Gall sawl rhaglennydd ysgrifennu'r cod ar unwaith (mae pob un yn ysgrifennu elfen ar wahân)
  • Mae profion awtomataidd yn cael eu symleiddio - po symlaf yw'r elfen, yr hawsaf yw profi
  • Mae cyfansoddiad y cod yn ymddangos - gallwch chi ei ddisodli YfedUpOperation i lawdriniaeth lle mae meddwyn yn tywallt hylif o dan y bwrdd. Neu disodli'r llawdriniaeth arllwys gyda llawdriniaeth lle rydych chi'n cymysgu gwin a dŵr neu fodca a chwrw. Yn dibynnu ar ofynion busnes, gallwch chi wneud popeth heb gyffwrdd â'r cod dull Tippler.Act.
  • O'r gweithrediadau hyn gallwch chi blygu'r glwton (gan ddefnyddio'n unig TakeBitOperation), Alcoholig (gan ddefnyddio yn unig YfedUpOperation yn syth o'r botel) a chwrdd â llawer o ofynion busnes eraill.

(O, mae'n ymddangos bod hon eisoes yn egwyddor OCP, ac fe wnes i dorri cyfrifoldeb y swydd hon)

Ac, wrth gwrs, yr anfanteision:

  • Bydd yn rhaid i ni greu mwy o fathau.
  • Mae meddwyn yn yfed am y tro cyntaf ychydig oriau yn hwyrach nag y byddai fel arall.

Diffiniad 2. Amrywioldeb unedig.

Caniatewch i mi, foneddigion! Mae gan y dosbarth yfed hefyd un cyfrifoldeb - mae'n yfed! Ac yn gyffredinol, mae’r gair “cyfrifoldeb” yn gysyniad hynod niwlog. Rhywun sy'n gyfrifol am dynged y ddynoliaeth, a rhywun sy'n gyfrifol am godi'r pengwiniaid gafodd eu gwyrdroi wrth y polyn.

Gadewch i ni ystyried dau weithrediad yr yfwr. Mae'r un cyntaf, a grybwyllir uchod, yn cynnwys tri dosbarth - arllwys, diod a byrbryd.

Ysgrifennir yr ail drwy'r fethodoleg “Ymlaen ac Ymlaen yn Unig” ac mae'n cynnwys yr holl resymeg yn y dull Gweithredu:

//Не тратьте время  на изучение этого класса. Лучше съешьте печеньку
с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);
    }
   }
}

Mae’r ddau ddosbarth hyn, o safbwynt sylwedydd allanol, yn edrych yn union yr un fath ac yn rhannu’r un cyfrifoldeb o “yfed”.

Dryswch!

Yna awn ar-lein i ddarganfod diffiniad arall o SRP - yr Egwyddor Newidadwyedd Sengl.

Mae SCP yn nodi bod "Mae gan fodiwl un a dim ond un rheswm dros newid" . Hynny yw, “Mae cyfrifoldeb yn rheswm dros newid.”

(Mae'n ymddangos bod y dynion a luniodd y diffiniad gwreiddiol yn hyderus yng ngalluoedd telepathig y dyn epa)

Nawr mae popeth yn disgyn i'w le. Ar wahân, gallwn newid y gweithdrefnau arllwys, yfed a byrbrydau, ond yn yr yfwr ei hun dim ond trefn a chyfansoddiad y llawdriniaeth y gallwn ei newid, er enghraifft, trwy symud y byrbryd cyn yfed neu ychwanegu darlleniad tost.

Yn y dull “Ymlaen ac Ymlaen yn Unig”, mae popeth y gellir ei newid yn cael ei newid yn y dull yn unig Gweithredu. Gall hyn fod yn ddarllenadwy ac yn effeithiol pan nad oes llawer o resymeg ac anaml y bydd yn newid, ond yn aml mae'n dod i ben mewn dulliau ofnadwy o 500 llinell yr un, gyda mwy o os-datganiadau nag sy'n ofynnol i Rwsia ymuno â NATO.

Diffiniad 3. Lleoli newidiadau.

Yn aml nid yw yfwyr yn deall pam eu bod wedi deffro yn fflat rhywun arall, neu ble mae eu ffôn symudol. Mae'n bryd ychwanegu logio manwl.

Gadewch i ni ddechrau logio gyda'r broses arllwys:

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}");
    }
}

Trwy ei amgáu i mewn Arllwysiad, gweithredasom yn ddoeth o safbwynt cyfrifoldeb ac amgyffrediad, ond yn awr yr ydym wedi ein drysu â'r egwyddor o amrywioldeb. Yn ogystal â'r llawdriniaeth ei hun, a all newid, mae'r logio ei hun hefyd yn dod yn gyfnewidiol. Bydd yn rhaid i chi wahanu a chreu cofnodwr arbennig ar gyfer y llawdriniaeth arllwys:

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)
        }
    }
}

Bydd y darllenydd manwl yn sylwi ar hynny LogAfter, LogCyn и OnGwall gellir ei newid yn unigol hefyd, ac, trwy gyfatebiaeth â'r camau blaenorol, bydd yn creu tri dosbarth: ArllwyswchLoggerCyn, ArllwyswchLoggerAr ol и PourErrorLogger.

A chofio bod tair llawdriniaeth i yfwr, rydyn ni'n cael naw dosbarth logio. O ganlyniad, mae'r cylch yfed cyfan yn cynnwys 14 (!!!) dosbarth.

Hyperbola? Prin! Bydd dyn mwnci â grenâd dadelfennu yn rhannu'r “arllwyswr” yn decanter, gwydr, gweithredwyr arllwys, gwasanaeth cyflenwi dŵr, model ffisegol o wrthdrawiad moleciwlau, ac am y chwarter nesaf bydd yn ceisio datrys y dibyniaethau hebddynt. newidynnau byd-eang. A chredwch fi, ni fydd yn stopio.

Ar y pwynt hwn y mae llawer yn dod i'r casgliad bod SRP yn straeon tylwyth teg o deyrnasoedd pinc, ac yn mynd i ffwrdd i chwarae nwdls ...

... heb ddysgu erioed am fodolaeth trydydd diffiniad o Srp:

“Mae’r Egwyddor Cyfrifoldeb Sengl yn nodi hynny dylai pethau sy'n debyg i newid gael eu storio mewn un lle" . neu "Dylid cadw'r hyn sy'n newid gyda'i gilydd mewn un lle"

Hynny yw, os byddwn yn newid logio gweithrediad, yna mae'n rhaid i ni ei newid mewn un lle.

Mae hwn yn bwynt pwysig iawn - gan fod yr holl esboniadau o SRP a oedd uchod yn dweud bod angen malu'r mathau tra'u bod yn cael eu malu, hynny yw eu bod yn gosod “terfyn uchaf” ar faint y gwrthrych, a nawr rydym eisoes yn sôn am “terfyn isaf”. Mewn geiriau eraill, Mae SRP nid yn unig yn gofyn am “falu wrth wasgu”, ond hefyd peidio â gorwneud pethau - “peidiwch â mathru pethau sy'n cyd-gloi”. Dyma'r frwydr fawr rhwng rasel Occam a'r dyn epa!

Egwyddor Cyfrifoldeb Sengl. Ddim mor syml ag y mae'n ymddangos

Nawr dylai'r yfwr deimlo'n well. Yn ogystal â'r ffaith nad oes angen rhannu'r cofnodwr IPourLogger yn dri dosbarth, gallwn hefyd gyfuno'r holl gofnodwyr yn un math:

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

Ac os ydym yn ychwanegu pedwerydd math o weithrediad, yna mae'r logio ar ei gyfer eisoes yn barod. Ac mae cod y gweithrediadau eu hunain yn lân ac yn rhydd o sŵn seilwaith.

O ganlyniad, mae gennym 5 dosbarth ar gyfer datrys y broblem yfed:

  • Arllwysiad gweithrediad
  • Gweithrediad yfed
  • Gweithrediad jamio
  • Logiwr
  • Ffasâd yfwr

Mae pob un ohonynt yn gwbl gyfrifol am un swyddogaeth ac mae ganddynt un rheswm dros newid. Mae'r holl reolau tebyg i newid wedi'u lleoli gerllaw.

Enghraifft o fywyd go iawn

Fe wnaethom unwaith ysgrifennu gwasanaeth ar gyfer cofrestru cleient b2b yn awtomatig. Ac ymddangosodd dull Duw ar gyfer 200 llinell o gynnwys tebyg:

  • Ewch i 1C a chreu cyfrif
  • Gyda'r cyfrif hwn, ewch i'r modiwl talu a'i greu yno
  • Gwiriwch nad yw cyfrif gyda chyfrif o'r fath wedi'i greu ar y prif weinydd
  • Creu cyfrif newydd
  • Ychwanegwch y canlyniadau cofrestru yn y modiwl talu a'r rhif 1c at y gwasanaeth canlyniadau cofrestru
  • Ychwanegu gwybodaeth cyfrif at y tabl hwn
  • Crëwch rif pwynt ar gyfer y cleient hwn yn y gwasanaeth pwyntiau. Pasiwch eich rhif cyfrif 1c i'r gwasanaeth hwn.

Ac roedd tua 10 yn fwy o weithrediadau busnes ar y rhestr hon gyda chysylltedd ofnadwy. Roedd angen gwrthrych y cyfrif ar bron pawb. Roedd angen rhif adnabod y pwynt ac enw'r cleient yn hanner y galwadau.

Ar ôl awr o ailffactorio, roeddem yn gallu gwahanu'r cod seilwaith a rhai o'r nawsau o weithio gyda chyfrif yn ddulliau/dosbarthiadau ar wahân. Roedd dull Duw yn ei gwneud hi'n haws, ond roedd 100 llinell o god ar ôl nad oeddent am gael eu datgymalu.

Dim ond ar ôl ychydig ddyddiau y daeth yn amlwg mai algorithm busnes yw hanfod y dull “ysgafn” hwn. A bod y disgrifiad gwreiddiol o'r manylebau technegol yn eithaf cymhleth. A'r ymgais i dorri'r dull hwn yn ddarnau a fydd yn torri'r SRP, ac nid i'r gwrthwyneb.

Ffurfioldeb.

Mae'n bryd gadael llonydd i'n meddwi. Sychwch eich dagrau - byddwn yn bendant yn dychwelyd ato ryw ddydd. Nawr, gadewch i ni ffurfioli'r wybodaeth o'r erthygl hon.

Ffurfioldeb 1. Diffiniad o SRP

  1. Gwahanwch yr elfennau fel bod pob un ohonynt yn gyfrifol am un peth.
  2. Ystyr cyfrifoldeb yw “rheswm i newid.” Hynny yw, dim ond un rheswm sydd gan bob elfen dros newid, o ran rhesymeg busnes.
  3. Newidiadau posibl i resymeg busnes. rhaid ei leoleiddio. Rhaid i elfennau sy'n newid yn gydamserol fod gerllaw.

Ffurfioldeb 2. Meini prawf hunan-brawf angenrheidiol.

Nid wyf wedi gweld digon o feini prawf ar gyfer cyflawni'r SRP. Ond mae amodau angenrheidiol:

1) Gofynnwch i chi'ch hun beth mae'r dosbarth/dull/modiwl/gwasanaeth hwn yn ei wneud. rhaid i chi ei ateb gyda diffiniad syml. ( Diolch Brightori )

esboniadau

Fodd bynnag, weithiau mae'n anodd iawn dod o hyd i ddiffiniad syml

2) Mae trwsio nam neu ychwanegu nodwedd newydd yn effeithio ar isafswm nifer o ffeiliau/dosbarthiadau. Yn ddelfrydol - un.

esboniadau

Gan fod cyfrifoldeb (am nodwedd neu fyg) wedi'i grynhoi mewn un ffeil/dosbarth, rydych chi'n gwybod yn union ble i edrych a beth i'w olygu. Er enghraifft: bydd y nodwedd o newid allbwn gweithrediadau logio yn gofyn am newid y cofnodwr yn unig. Nid oes angen rhedeg trwy weddill y cod.

Enghraifft arall yw ychwanegu rheolydd UI newydd, tebyg i'r rhai blaenorol. Os yw hyn yn eich gorfodi i ychwanegu 10 endid gwahanol a 15 o drawsnewidwyr gwahanol, mae'n edrych fel eich bod chi'n gorwneud hi.

3) Os yw sawl datblygwr yn gweithio ar wahanol nodweddion eich prosiect, yna mae'r tebygolrwydd o wrthdaro uno, hynny yw, y tebygolrwydd y bydd yr un ffeil / dosbarth yn cael ei newid gan sawl datblygwr ar yr un pryd, yn fach iawn.

esboniadau

Os, wrth ychwanegu gweithrediad newydd "Arllwyswch fodca o dan y bwrdd", mae angen i chi effeithio ar y cofnodwr, gweithrediad yfed ac arllwys, yna mae'n edrych fel bod y cyfrifoldebau wedi'u rhannu'n gam. Wrth gwrs, nid yw hyn bob amser yn bosibl, ond dylem geisio lleihau’r ffigur hwn.

4) Pan ofynnir cwestiwn eglurhaol am resymeg busnes (gan ddatblygwr neu reolwr), rydych chi'n mynd yn gaeth i un dosbarth / ffeil ac yn derbyn gwybodaeth oddi yno yn unig.

esboniadau

Mae nodweddion, rheolau neu algorithmau wedi'u hysgrifennu'n gryno, pob un mewn un lle, ac nid yw wedi'i wasgaru â baneri ledled y gofod cod.

5) Mae'r enw yn glir.

esboniadau

Mae ein dosbarth neu ein dull yn gyfrifol am un peth, ac adlewyrchir y cyfrifoldeb yn ei enw

AllManagersManagerService - dosbarth Duw yn fwyaf tebygol
Taliad Lleol - nid yw'n debyg

Ffurfioldeb 3. Methodoleg datblygu Occam-First.

Ar ddechrau'r dyluniad, nid yw'r dyn mwnci yn gwybod ac nid yw'n teimlo holl gynildeb y broblem sy'n cael ei datrys a gall wneud camgymeriad. Gallwch chi wneud camgymeriadau mewn gwahanol ffyrdd:

  • Gwnewch wrthrychau'n rhy fawr trwy gyfuno gwahanol gyfrifoldebau
  • Ail-fframio trwy rannu un cyfrifoldeb yn nifer o wahanol fathau
  • Diffinio ffiniau cyfrifoldeb yn anghywir

Mae’n bwysig cofio’r rheol: “mae’n well gwneud camgymeriad mawr,” neu “os nad ydych chi’n siŵr, peidiwch â’i wahanu.” Er enghraifft, os yw eich dosbarth yn cynnwys dau gyfrifoldeb, yna mae'n ddealladwy o hyd a gellir ei rannu'n ddau heb fawr o newidiadau i'r cod cleient. Mae cydosod gwydraid o ddarnau o wydr fel arfer yn anoddach oherwydd bod y cyd-destun yn cael ei wasgaru ar draws sawl ffeil a'r diffyg dibyniaethau angenrheidiol yn y cod cleient.

Mae'n bryd ei alw'n ddiwrnod

Nid yw cwmpas SRP wedi'i gyfyngu i OOP a SOLID. Mae'n berthnasol i ddulliau, swyddogaethau, dosbarthiadau, modiwlau, microwasanaethau a gwasanaethau. Mae'n berthnasol i ddatblygiad “figax-figax-and-prod” a “gwyddoniaeth roced”, gan wneud y byd ychydig yn well ym mhobman. Os meddyliwch am y peth, dyma bron egwyddor sylfaenol pob peirianneg. Mae peirianneg fecanyddol, systemau rheoli, ac yn wir yr holl systemau cymhleth yn cael eu hadeiladu o gydrannau, ac mae “tanddarnio” yn amddifadu dylunwyr o hyblygrwydd, mae “gorddarnio” yn amddifadu dylunwyr o effeithlonrwydd, ac mae ffiniau anghywir yn eu hamddifadu o reswm a thawelwch meddwl.

Egwyddor Cyfrifoldeb Sengl. Ddim mor syml ag y mae'n ymddangos

Nid yw SRP wedi'i ddyfeisio gan natur ac nid yw'n rhan o wyddoniaeth fanwl gywir. Mae'n torri allan o'n cyfyngiadau biolegol a seicolegol, dim ond ffordd o reoli a datblygu systemau cymhleth gan ddefnyddio'r ymennydd epa-ddyn ydyw. Mae'n dweud wrthym sut i ddadelfennu system. Roedd angen cryn dipyn o delepathi ar y fformiwleiddiad gwreiddiol, ond rwy'n gobeithio y bydd yr erthygl hon yn clirio rhywfaint o'r sgrin fwg.

Ffynhonnell: hab.com

Ychwanegu sylw