Принсипи масъулиятшиносии ягона. На он қадар оддӣ, ки ба назар мерасад

Принсипи масъулиятшиносии ягона. На он қадар оддӣ, ки ба назар мерасад Принсипи масъулияти ягона, ки ҳамчун принсипи масъулияти ягона маълум аст,
aka принсипи тағйирпазирии якхела - як бачаи бениҳоят лағжанда барои фаҳмидан ва чунин саволи асабонӣ дар мусоҳибаи барномасоз.

Аввалин ошноии чиддии ман бо ин принцип дар ибтидои курси якум, вакте ба амал омад, ки чаво-нону сабзу хуррамро ба чангал бурда, аз кирмак студентон — студентони асил.

Дар чангал моро ба гурУххои 8—9-нафарй таксим карда, мусобика мекардем — кадом гурух тезтар як шиша арак менушад, ба шарте, ки шахси якум аз гурух ба стакан арак резад, дуюмаш онро менушад. сеюм бошад, газак дорад. Шӯъбае, ки корашро анҷом додааст, ба охири навбати гурӯҳ мегузарад.

Ҳолате, ки андозаи навбат ба се баробар буд, татбиқи хуби SRP буд.

Таърифи 1. Масъулияти ягона.

Дар таърифи расмии Принсипи Масъулияти Ягона (SRP) гуфта мешавад, ки ҳар як субъект масъулият ва сабаби мавҷудияти худро дорад ва он танҳо як масъулият дорад.

Объекти "Нӯшок"-ро баррасӣ кунед (Типплер).
Барои татбиқи принсипи SRP, мо масъулиятҳоро ба се тақсим мекунем:

  • Яке мерезад (PourOperation)
  • Як менӯшад (DrinkUpOperation)
  • Яке газак дорад (TakeBiteOperation)

Ҳар як иштирокчии ин раванд барои як ҷузъи раванд масъул аст, яъне як масъулияти атомиро дорад - нӯшидан, рехтан ё газак кардан.

Сӯрохи нӯшокӣ, дар навбати худ, як фасад барои ин амалиётҳо мебошад:

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

Принсипи масъулиятшиносии ягона. На он қадар оддӣ, ки ба назар мерасад

Чаро?

Барномасози инсонӣ барои одами маймун код менависад ва маймуни одам бепарво, аблаҳ ва ҳамеша шитоб мекунад. Вай метавонад дар як вақт тақрибан 3 - 7 истилоҳро дошта бошад ва бифаҳмад.
Дар мавриди майзада се истилоҳ вуҷуд дорад. Аммо агар кодро бо як варақ нависем, дар он дасту айнак, задухӯрд ва баҳсҳои беохир дар бораи сиёсат хоҳад буд. Ва ҳамаи ин дар бадани як усул хоҳад буд. Боварй дорам, ки шумо дар амалияи худ чунин кодро дидаед. Санҷиши аз ҳама инсондӯстона барои равоншиносӣ нест.

Аз тарафи дигар, одами маймун барои тақлид кардани ашёҳои ҷаҳони воқеӣ дар сари ӯ тарҳрезӣ шудааст. Вай дар хаёли худ метавонад онҳоро ба ҳам тела диҳад, аз онҳо ашёи нав ҷамъ кунад ва ҳамин тавр ба қисмҳо ҷудо кунад. Мошини кӯҳнаро тасаввур кунед. Дар тасаввуроти худ, шумо метавонед дарро кушоед, ороиши дарро кушоед ва дар он ҷо механизмҳои бардорандаи тирезаро бинед, ки дар дохили онҳо фишангҳо мавҷуданд. Аммо хамаи кисмхои дастгохро дар як вакт, дар як «листинг» дидан мумкин нест. Ақаллан "марди маймун" наметавонад.

Аз ин рӯ, барномасозони инсонӣ механизмҳои мураккабро ба маҷмӯи унсурҳои камтар мураккаб ва корӣ тақсим мекунанд. Аммо онро бо тарзҳои гуногун таҷзия кардан мумкин аст: дар бисёре аз мошинҳои кӯҳна канали ҳавоӣ ба дар дохил мешавад ва дар мошинҳои замонавӣ нокомии электроникаи қулф аз ба кор андохтани муҳаррик монеъ мешавад, ки дар вақти таъмир мушкилӣ эҷод мекунад.

Ҳоло, SRP як принсипест, ки ТАРЗИ таҷзия кардан, яъне дар куҷо кашидани хати тақсимкуниро мефаҳмонад.

У мегуяд, ки аз руи принципи таксимоти «масъулият», яъне аз руи вазифахои объектхои алохида таксим кардан лозим аст.

Принсипи масъулиятшиносии ягона. На он қадар оддӣ, ки ба назар мерасад

Биёед ба нӯшидан ва бартариҳое, ки одами маймун ҳангоми таҷзия ба даст меорад, бармегардем:

  • Рамз дар ҳама сатҳҳо хеле равшан шудааст
  • Рамзро дар як вақт якчанд барномасозон навишта метавонанд (ҳар як унсури алоҳида менависад)
  • Санҷиши автоматикунонидашуда содда карда шудааст - элемент ҳар қадар соддатар бошад, озмоиши он осонтар аст
  • Композитсияи код пайдо мешавад - шумо метавонед иваз кунед DrinkUpOperation ба операцияе, ки дар он майзада ба зери миз моеъ мерезад. Ё амалиёти рехтанро бо амалиёте иваз кунед, ки дар он май ва об ё араку пиво омехта кунед. Вобаста ба талаботи тиҷорат, шумо метавонед ҳама чизро бе ламс кардани коди усул иҷро кунед Tippler. Act.
  • Аз ин амалиётҳо шумо метавонед пурхӯриро (танҳо бо истифода аз TakeBitOperation), Алкоголӣ (танҳо бо истифода аз DrinkUpOperation рост аз шиша) ва ба бисёр дигар талаботҳои тиҷоратӣ ҷавобгӯ мебошанд.

(Оҳ, ба назар чунин мерасад, ки ин аллакай як принсипи OCP аст ва ман масъулияти ин постро вайрон кардам)

Ва, албатта, манфии:

  • Мо бояд навъҳои бештар эҷод кунем.
  • Бадмаст бори аввал ду соат дертар аз он менӯшад, ки дар акси ҳол мебуд.

Таърифи 2. Тағйирпазирии ягона.

Иҷозат диҳед, ҷанобон! Синфи нӯшокӣ низ масъулияти ягона дорад - он менӯшад! Ва умуман, вожаи «масъулият» мафҳуми ниҳоят норавшан аст. Касе барои сарнавишти инсоният масъул аст ва касе барои парвариши пингвинҳои дар қутб чаппашуда масъул аст.

Биёед ду амалисозии нӯшокро баррасӣ кунем. Якум, ки дар боло зикр шуд, дорои се синф аст - рехт, бинӯшед ва газак.

Дуюм тавассути методологияи "Ба пеш ва танҳо ба пеш" навишта шудааст ва тамоми мантиқи усулро дар бар мегирад амал:

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

Ҳардуи ин синфҳо, аз нигоҳи як нозири беруна, маҳз як хел ба назар мерасанд ва масъулияти “нӯшидан”-ро доранд.

Нофаҳмиҳо!

Сипас мо ба интернет меравем ва таърифи дигари SRP - Принсипи ягонаи тағирёбандаро мефаҳмем.

SCP мегӯяд, ки "Модул як ва танҳо як сабаби тағир додан дорад". Яъне, "Масъулият сабаби тағирот аст".

(Ба назар чунин мерасад, ки бачаҳое, ки таърифи аслиро таҳия кардаанд, ба қобилиятҳои телепатикии одами маймун боварӣ доштанд)

Акнун ҳама чиз ба ҷои худ меафтад. Алоҳида, мо метавонем расмиёти рехтан, нӯшидан ва нӯшиданро тағир диҳем, аммо дар худи нӯшокӣ мо метавонем пайдарпайӣ ва таркиби амалиётҳоро тағир диҳем, масалан, бо ҳаракат додани газак пеш аз нӯшидан ё илова кардани хониши тост.

Дар равиши "Ба пеш ва танҳо ба пеш" ҳама чизеро, ки тағир додан мумкин аст, танҳо дар усул тағир медиҳад амал. Ин метавонад хонданшаванда ва муассир бошад, вақте ки мантиқ кам аст ва он хеле кам тағир меёбад, аммо аксар вақт он бо усулҳои даҳшатноки ҳар кадоми 500 сатр ва бо изҳороти бештар аз он ки барои ворид шудан ба НАТО зарур аст, анҷом меёбад.

Муайянкунии 3. Маҳаллисозии тағйирот.

Нӯшандагон аксар вақт намефаҳманд, ки чаро онҳо дар манзили ягон каси дигар бедор шудаанд ва ё телефони мобилии онҳо дар куҷост. Вақти он расидааст, ки сабти муфассалро илова кунед.

Биёед бо раванди рехтан ба қайдгири оғоз кунем:

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

Бо фарогирии он дар PourOperation, мо аз нуктаи назари масъулиятшиносй ва ин-кишофи хирадмандона амал мекардем, вале акнун бо принципи тагйирпазирй ошуфта шудааст. Илова ба худи амалиёт, ки метавонад тағир ёбад, худи сабт низ тағйирёбанда мешавад. Ба шумо лозим меояд, ки барои амалиёти рехтан як логгери махсусро ҷудо ва эҷод кунед:

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

Хонандаи бодиққат инро пай мебарад LogAfter, LogBefore и OnError инчунин метавонад ба таври инфиродӣ тағир дода шавад ва дар муқоиса бо қадамҳои қаблӣ, се синф эҷод мекунад: PourLoggerBefore, PourLoggerAfter и PourErrorLogger.

Ва дар хотир дорем, ки барои майхӯр се амалиёт вуҷуд дорад, мо нӯҳ синфҳои дарахтбуриро мегирем. Дар натича тамоми кружоки нушокй аз 14 (!!!) синф иборат аст.

Гипербола? Базӯр! Марди маймун бо гранатаи таҷзияшаванда "рехтан" -ро ба графин, шиша, операторҳои рехтагарӣ, хадамоти обтаъминкунӣ, модели физикии бархӯрди молекулаҳо тақсим мекунад ва дар семоҳаи оянда вай кӯшиш мекунад, ки вобастагиҳоро бидуни он ҳал кунад. тағирёбандаҳои глобалӣ. Ва ба ман бовар кунед, вай бас намекунад.

Маҳз дар ҳамин лаҳза бисёриҳо ба хулосае меоянд, ки СРП афсонаҳои салтанатҳои гулобӣ аст ва барои угро бозӣ кардан мераванд...

... бидуни ҳеҷ гоҳ дар бораи мавҷудияти таърифи сеюми Srp омӯхта нашудааст:

«Принципи масъулиятшиносии ягона гуфта мешавад, ки чизхое, ки ба тагйир монанданд, бояд дар як чо нигох дошта шаванд". ё"Кадом тағирот бояд дар як ҷо нигоҳ дошта шаванд"

Яъне, агар мо сабти амалиётро тағир диҳем, пас мо бояд онро дар як ҷо иваз кунем.

Ин як нуктаи хеле муҳим аст - зеро ҳама тавзеҳоти SRP, ки дар боло гуфта шуда буданд, мегӯянд, ки навъҳоро ҳангоми майда кардан лозим аст, яъне онҳо ба андозаи объект "ҳадди болоӣ" гузоштаанд ва ҳоло. мо аллакай дар бораи "лимити поёнӣ" гап мезанем. Ба ибораи дигар, SRP на танҳо "ҳангоми майда кардан" -ро талаб мекунад, балки аз ҳад зиёд наравед - "чизҳои ба ҳам пайвастшударо майда накунед". Ин ҷанги бузург байни риштаи Оккам ва одами маймун аст!

Принсипи масъулиятшиносии ягона. На он қадар оддӣ, ки ба назар мерасад

Акнун нӯшанда бояд худро беҳтар ҳис кунад. Илова бар он, ки лозим нест, ки сабти IPourLogger ба се синф тақсим карда шавад, мо инчунин метавонем ҳамаи логгерҳоро ба як намуд муттаҳид кунем:

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

Ва агар мо намуди чоруми амалиётро илова кунем, пас сабти он аллакай омода аст. Ва худи рамзи амалиёт тоза ва аз садои инфрасохтор озод аст.

Дар натиҷа, мо барои ҳалли мушкилоти нӯшокӣ 5 синф дорем:

  • Амалиёти рехтан
  • Амалиёти нӯшокӣ
  • Амалиёти басташавӣ
  • Логгер
  • Фасади нӯшокӣ

Ҳар яке аз онҳо ба таври қатъӣ барои як функсия масъуланд ва як сабаби тағирот доранд. Ҳама қоидаҳое, ки ба тағирот монанданд, дар наздикӣ ҷойгиранд.

Намунаи ҳаёти воқеӣ

Мо боре хидмате навиштем, ки ба таври худкор бақайдгирии муштарии b2b. Ва усули ХУДО барои 200 сатри мундариҷаи шабеҳ пайдо шуд:

  • Ба 1C равед ва ҳисоб эҷод кунед
  • Бо ин ҳисоб, ба модули пардохт гузаред ва онро дар он ҷо эҷод кунед
  • Тафтиш кунед, ки ҳисоб бо чунин ҳисоб дар сервери асосӣ сохта нашудааст
  • Ҳисоби нав эҷод кунед
  • Натиҷаҳои бақайдгирӣ дар модули пардохт ва рақами 1c ба хидмати натиҷаҳои бақайдгирӣ илова кунед
  • Маълумоти ҳисобро ба ин ҷадвал илова кунед
  • Барои ин муштарӣ дар хидмати нуқта рақами нуқта эҷод кунед. Рақами ҳисоби 1c-и худро ба ин хидмат интиқол диҳед.

Ва дар ин рӯйхат тақрибан 10 амалиёти дигари тиҷоратӣ бо пайвасти даҳшатнок мавҷуд буданд. Қариб ҳама ба объекти ҳисоб ниёз доштанд. Дар нисфи зангҳо ID нуқта ва номи муштарӣ лозим буд.

Пас аз як соати рефакторинг, мо тавонистем рамзи инфрасохтор ва баъзе нозукиҳои кор бо ҳисобро ба усулҳо/синфҳои алоҳида ҷудо кунем. Усули Худо онро осонтар кард, аммо 100 хати рамз боқӣ монда буд, ки онҳо намехоҳанд ҳаллу фасл шаванд.

Танҳо пас аз чанд рӯз маълум шуд, ки моҳияти ин усули "сабук" як алгоритми тиҷорат аст. Ва тавсифи аслии мушаххасоти техникӣ хеле мураккаб буд. Ва махз кушиши ба порахо чудо кардани ин усул СРП-ро вайрон мекунад, на баръакс.

формализм.

Вакти он расидааст, ки масти моро танхо гузорем. Ашки худро хушк кунед - мо ҳатман рӯзе ба он бармегардем. Акнун биёед донишро аз ин мақола ба расмият меорем.

Формализм 1. Таърифи СРП

  1. Унсурҳоро ҷудо кунед, то ки ҳар яки онҳо барои як чиз масъул бошанд.
  2. Масъулият маънои "сабаби тағир додан" -ро дорад. Яъне, ҳар як унсур танҳо як сабаби тағирот дорад, аз нуқтаи назари мантиқи тиҷорат.
  3. Тағироти эҳтимолӣ дар мантиқи тиҷорат. бояд махаллй гардонда шавад. Унсурҳое, ки ба таври синхронӣ тағир меёбанд, бояд дар наздикӣ бошанд.

Формализм 2. Меъёрхои зарурии худидоракунй.

Ман меъёрҳои кофӣ барои иҷрои SRP надидам. Аммо шароити зарурӣ вуҷуд дорад:

1) Аз худ бипурсед, ки ин синф/усул/модул/хизмат чӣ кор мекунад. шумо бояд ба он бо таърифи оддӣ ҷавоб диҳед. ( Сипос Брайтори )

тавзеҳот

Бо вуҷуди ин, баъзан пайдо кардани таърифи оддӣ хеле душвор аст

2) Ислоҳи хато ё илова кардани хусусияти нав ба шумораи ҳадди ақали файлҳо/синфҳо таъсир мерасонад. Идеалӣ - як.

тавзеҳот

Азбаски масъулият (барои хусусият ё хато) дар як файл/синф фаро гирифта шудааст, шумо аниқ медонед, ки ба куҷо нигоҳ кардан ва чиро таҳрир кардан лозим аст. Масалан: хусусияти таѓйир додани натиљаи амалиётњои баќайдгирї таѓйир додани танњо сабткунандаро талаб мекунад. Ба воситаи қисми боқимондаи код кор кардан лозим нест.

Мисоли дигар ин илова кардани назорати нави UI мебошад, ки ба назорати қаблӣ монанд аст. Агар ин шуморо маҷбур кунад, ки 10 объекти гуногун ва 15 табдилдиҳандаи гуногунро илова кунед, чунин ба назар мерасад, ки шумо онро аз ҳад зиёд иҷро карда истодаед.

3) Агар якчанд таҳиягарон бо хусусиятҳои гуногуни лоиҳаи шумо кор кунанд, пас эҳтимолияти конфликти якҷоякунӣ, яъне эҳтимолияти тағир додани як файл/синф аз ҷониби якчанд таҳиягарон дар як вақт хеле кам аст.

тавзеҳот

Агар хангоми илова кардани операцияи нави «Дар зери дастархон арак резед» ба логар, ба амалиёти нушидан ва рехтан таъсир расондан лозим бошад, пас чунин ба назар мерасад, ки масъулият каҷ таксим шудааст. Албатта, ин на ҳама вақт имконпазир аст, аммо мо бояд кӯшиш кунем, ки ин рақамро кам кунем.

4) Вақте ки саволи равшанкунанда дар бораи мантиқи тиҷорат дода мешавад (аз таҳиягар ё менеҷер), шумо ба таври қатъӣ ба як синф/файл дохил мешавед ва танҳо аз он ҷо маълумот мегиред.

тавзеҳот

Хусусиятҳо, қоидаҳо ё алгоритмҳо ба таври мӯътадил, ҳар як дар як ҷо навишта шудаанд ва бо парчамҳо дар тамоми фазои код пароканда нестанд.

5) Номгузорӣ равшан аст.

тавзеҳот

Синф ё методи мо барои як чиз масъул аст ва масъулият дар номи он инъикос меёбад

AllManagersManagerService - эҳтимолан синфи Худо
LocalPayment - эҳтимол не

Формализм 3. Оккам-аввал методологияи инкишоф.

Дар ибтидои тарроҳӣ одами маймун тамоми нозукиҳои ҳалли масъаларо намедонад ва эҳсос намекунад ва метавонад хато кунад. Шумо метавонед бо роҳҳои гуногун хато кунед:

  • Бо якҷоя кардани масъулиятҳои гуногун объектҳоро хеле калон кунед
  • Бозсозӣ бо роҳи тақсим кардани як масъулият ба намудҳои гуногуни гуногун
  • ХУДУДИ масъулиятро нодуруст муайян кунед

Дар хотир доштан муҳим аст, ки қоида: "беҳтар аст, ки хатои калон кунед" ё "агар шумо боварӣ надошта бошед, онро тақсим накунед." Агар, масалан, синфи шумо ду масъулият дошта бошад, он ҳоло ҳам фаҳмо аст ва онро бо тағироти ҳадди ақали коди муштарӣ ба ду тақсим кардан мумкин аст. Ҷамъоварии шиша аз пораҳои шиша одатан аз сабаби паҳн шудани контекст дар якчанд файлҳо ва набудани вобастагии зарурӣ дар коди муштарӣ мушкилтар аст.

Вакти он расидааст, ки онро як руз даъват кунем

Доираи SRP бо OOP ва SOLID маҳдуд намешавад. Он ба усулҳо, функсияҳо, синфҳо, модулҳо, микросервисҳо ва хидматҳо дахл дорад. Он ҳам ба рушди "figax-figax-and-prod" ва "илми ракетӣ" дахл дорад ва ҷаҳонро дар ҳама ҷо каме беҳтар мекунад. Агар шумо дар ин бора фикр кунед, ин қариб принсипи асосии тамоми муҳандисӣ аст. Машинасозй, системахои идоракунй ва дар хакикат хамаи системахои мураккаб аз кисмхо сохта шудаанд ва «кампоракунй» конструкторонро аз чандирй, «аз хад зиёд фрагментатсия» конструкторонро аз самаранокй ва сархадхои нодуруст онхоро аз аклу хирад ва оромии рух махрум мекунад.

Принсипи масъулиятшиносии ягона. На он қадар оддӣ, ки ба назар мерасад

SRP табиатан ихтироъ нашудааст ва ҷузъи илми дақиқ нест. Он аз маҳдудиятҳои биологӣ ва психологии мо берун мебарояд Ин танҳо як роҳи назорат ва рушди системаҳои мураккаб бо истифода аз майнаи одами маймун аст. Вай ба мо мегӯяд, ки чӣ тавр системаро вайрон кардан лозим аст. Тарҳрезии аслӣ миқдори одилонаи телепатияро талаб мекард, аммо ман умедворам, ки ин мақола як қисми пардаи дудро тоза мекунад.

Манбаъ: will.com

Илова Эзоҳ