Միասնական պատասխանատվության սկզբունքը (SRP) նշում է, որ ծրագրային ապահովման մոդուլները (Դասեր և մեթոդներ) պետք է ունենան մեկ նպատակ: Ռոբերտ Ս. Մարտինի խոսքերով՝ վարպետ վարպետ, ով հորինել է տերմինը, դասերը պետք է փոխվելու միայն մեկ պատճառ ունենան։ Պատճառը, թե ինչու ես ձգտում եմ գրել SRP-ին համապատասխանող կոդ, այն է, որ այն դարձնում է կոդը ընթեռնելի, ստուգելի, փոփոխելի և : բազմակի օգտագործման։ SRP-ն կիրառվում է ինչպես օբյեկտ կողմնորոշված, այնպես էլ ֆունկցիոնալ ծրագրավորման լեզուների համար: Այս բլոգը օգտագործում է Clojure-ի օրինակներ, այնպես որ ես կպատմեմ, թե ինչպես կարելի է գործառույթները գրել SRP-ին հետևելու համար:
SRP-ին համապատասխանող կոդը կարդալն ավելի հեշտ է հետևել, քանի որ այն կենտրոնացած է և հակիրճ: Գործառույթը, որը չափազանց շատ բաներ է անում իր պարտականությունների շրջանակից դուրս, ստեղծում է անհարկի խճճվածություններ, որոնք դժվարացնում են կարդալը և վրիպազերծումը: Նայեք ստորև բերված պարզ օրինակին.
(defn calc-bill [menu-item-values] (reduce + menu-item-values)) (defn print-bill [total-value] (str "Your total value is $" total-value))
Առաջին ֆունկցիան հաշվարկում է հաշիվը, իսկ երկրորդ ֆունկցիան տպում է հաշիվը՝ հիմնվելով ընդհանուր արժեքի վրա: Յուրաքանչյուր գործառույթ ունի մեկ հստակ պատասխանատվություն և դրանով իսկ հեշտացնում է այն հետևելը: Կոդի ընթեռնելիությունը օգնում է պահպանման և վրիպազերծման խնդիրներին:
Ավելի հեշտ է ստուգել գործառույթները, որոնք կատարում են մեկ հիմնական գործողություն: Որպես օրինակ, ես կարող եմ հեշտությամբ ստեղծել միավորի թեստ իմ calc-bill ֆունկցիայի համար: Ստորև բերված օրինակով.
(deftest test-calc-bill (testing "Calculating Bill" (is (= (calc-bill 20 12 2) 34)) (is (= (calc-bill 10 20) 30)) (is (= (calc-bill 30 42) 72 ))))
Եթե ես ունենայի մեկ գործառույթ հաշիվը հաշվարկելու և տպելու համար, ապա ես այլևս չեմ փորձարկում ամենափոքր հնարավոր միավորը:
Անխուսափելի է, որ արտաքին գործոնները, ինչպիսիք են բիզնեսի նոր պահանջները կամ գրադարանների թարմացումները, կպահանջեն փոփոխություններ կատարել կոդերի բազայում: Հետևաբար, անջատված կոդը կհեշտացնի փոփոխությունն իրականացնող ծրագրավորողի կյանքը: Վերջին բանը, որ ցանկանում է ցանկացած ծրագրավորող, մեկ փոփոխություն կատարելն է և կասկադային էֆեկտ ստեղծել համակարգի մնացած մասի վրա: Մեր օրինակում փոփոխություններ կարող են կատարվել ռեստորանի կողմից հաշիվը հաշվարկելու ձևի մեջ (ավելացնելով հարկերը, զեղչերը և այլն), առանց որևէ ազդեցություն թողնելու հաշիվը տպելու վրա:
Երբ վարքագծերը վերացվում և սահմանվում են գործառույթների մեջ, որոնք ունեն մեկ նպատակ, գործառույթներն ավելի հավանական է, որ օգտագործվեն հավելվածի այլ մասերում: Ռեստորանի սեփականատերը ցանկանում է հարկեր կիրառել օրինագծի վրա, ինչպես նաև հնարավորություն ունի հաշվարկել անհատականացված հաշիվ յուրաքանչյուր այցելուի համար, ով կիսում է սեղանը:
(defn apply-tax [total] (* 1.075 total)) (defn calc-personalized-bill-for-table [table-order] (into {} (map (fn [[k v]] [k (apply-tax (calc-bill v))]) table-order)))
calc-personalized-bill-for-table ֆունկցիան օգտագործում է calc-bill ֆունկցիան: Սա նվազեցնում է SRP-ին հաջորդող կոդ գրելու արտադրանքի ավելորդությունը կոդի մեջ:
SRP-ի օգուտները պարզ են. Երբ ես կասկածում եմ, թե արդյոք գործառույթը համապատասխանում է ՊԵԿ-ին: Փորձում եմ բացատրել, թե ինչ է անում այդ գործառույթը: Եթե ես պետք է օգտագործեմ և կամ կամ շաղկապները, ապա հավանական է, որ գործառույթը չի համապատասխանում SRP-ին: Սա Սանդի Մեց-ի հնարք էր, որը տրված էր իր Գործնական օբյեկտների վրա հիմնված դիզայն Ռուբիում վերնագրով գրքում: Ռոբերտ Ս. Մարտին-ի մեկ այլ առողջական վիճակի ստուգում է` որոշել, թե արդյոք այդ ծրագրային մոդուլի փոփոխության հարցումը բխում է տարբեր բիզնես գործառույթներից: Եթե նրանք անեն, ապա հնարավորություն կա վերափոխելու SRP-ի համար: