Միասնական պատասխանատվության սկզբունքը (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-ի համար: