SOLID: Կախվածության ինվերսիայի սկզբունքը
Բոլոր ծրագրերը կազմված են գործառույթներից և տվյալների կառուցվածքներից: Ռոբերտ Ք. Մարտինի կողմից ներկայացված SOLID սկզբունքներն օգնում են մեզ խմբավորել մեր կոդը մոդուլների մեջ և խորհուրդ տալ, թե ինչպես դրանք փոխկապակցել: Դիմումների ճարտարապետության ամբողջ իմաստը փոփոխությունը կառավարելն է: Ծրագրային ապահովման պահանջները անընդհատ փոխվում են, և մենք՝ որպես մշակողներ, պետք է համոզվենք, որ այս փոփոխությունները չեն խախտում գոյություն ունեցող կոդը:
Կա 5 սկզբունք, որոնք կազմում են հապավումը.
- S. Single Responsibility
- O: Բաց — Փակ
- Լ. Լիսկովի փոխարինում.
- Ես. ինտերֆեյսի տարանջատում
- D: Կախվածության շրջում
Այս սկզբունքներից յուրաքանչյուրը կարող է ինքնուրույն կանգնել: Ես լուսաբանել եմ Միասնական պատասխանատվության սկզբունքը և SOLID սկզբունքների այս երկրորդ գրառման մեջ ես կփորձեմ բացատրել DIP-ը (Կախվածության ինվերսիոն սկզբունքը):
DIP-ը մեզ ասում է, որ առավել ճկուն համակարգերն այն համակարգերն են, որոնցում ելակետային կոդի կախվածությունը վերաբերում է միայն աբստրակցիային, այլ ոչ թե իրականացումներին:
Այլ կերպ ասած, բարձր մակարդակի մոդուլները չպետք է կախված լինեն ցածր մակարդակի մոդուլներից, այլ պետք է կախված լինեն դրանց վերացականությունից:
Լավ, եկեք սկսենք բացահայտելով այն խնդիրը, որը մենք փորձում ենք լուծել: Եկեք ստեղծենք ցածր մակարդակի օգտագործողների պահեստի մոդուլ/դաս.
և բարձր մակարդակի դաս, որն օգտագործում է/կախված է օգտագործողի պահոցից.
և բարձր մակարդակի դասն օգտագործելու համար մենք անում ենք հետևյալը.
Խնդիրը GetAllUsers դասի մեջ է: Մենք ունենք ուղիղ կամ կոշտ կախվածություն «GetAllUsers» և «UserRepository» դասի միջև, ինչպես նշված է ներմուծման հայտարարության և նոր UserRepository օրինակի ստեղծման մեջ:
Եթե մենք ներմուծում էինք համակարգ, շրջանակային գրադարան կամ որևէ ստատիկ կախվածություն, ապա դա պետք է լավ լինի, այնուամենայնիվ, ակտիվորեն զարգացող մոդուլի նման մի բանի համար, որպես օգտագործողի պահոց, նպատակահարմար կլիներ չունենալ կոշտ կախվածություն, ինչպես մենք անում ենք այստեղ բարձր մակարդակի սահմաններում: - մակարդակի մոդուլ
Ինչու՞ է սա խնդիր:
Դե, եթե մենք սերտորեն զուգակցենք բարձր մակարդակի բաղադրիչը («GetAllUsers») ցածր մակարդակի կախվածությունների հետ (օգտագործողի պահեստ), ապա փոփոխությունները ռիսկային են: Բարձր մակարդակի մոդուլի ուժը ուղղակիորեն կախված է ցածր մակարդակի մոդուլի ուժից:
Այնուամենայնիվ, եթե մենք կախված ենք կախվածության միջերեսից/աբստրակցիայից, ապա մենք նվազեցնում ենք ռիսկը բարձր մակարդակի բաղադրիչների համար:
Եկեք փոխենք ծածկագիրը պատկերացնելու համար: Մենք բաժանում ենք օգտագործողի պահոցը ինտերֆեյսի և իրականացման
Փոխենք նաև ավելի բարձր մակարդակի մոդուլը
Այժմ մենք ունենք բարձր մակարդակի դաս, որը ուղղակիորեն կախված չէ ստորին մակարդակի մոդուլից, այլ դրա միջերեսից կամ վերացականությունից: Բարձր մակարդակը նաև չի «նորացնում» օգտվողների պահեստի ներդրումը
Մենք դրանք բոլորը միասին ենք դնում հետևյալ կերպ.
Այժմ կախվածությունների ստեղծումը շրջված է: Ստորին մակարդակի դասերը ստեղծվում են առաջին, այնուհետև կոնստրուկտորի միջոցով ներարկվում են բարձր մակարդակի դաս:
Սա հիանալի է կախվածությունները փոխարինելու համար, հատկապես միավորի փորձարկման ժամանակ, քանի որ մենք կարող ենք ավելի բարձր մակարդակի մոդուլները մեկուսացված փորձարկել՝ նրանց տրամադրելով կեղծ կախվածություններ: