Ի՞նչ է կախվածությունների մուտքի (Dependency Injection) առանձնահատկությունը։
sobes.tech AI
Պատասխան AI-ից
Ներգրավման առանձնահատկությունը (DI) այն է, որ կախվածությունների ստեղծումը և կառավարումը փոխանցվում է ինքնին օբյեկտից դուրս, սովորաբար IoC կոնտեյների (Inversion of Control)։ Փոխարենը, որ օբյեկտը ինքն է ստեղծում կամ գտնում իր կախվածությունները, դրանք «ներդրվում» են դուրսից։
Հիմնական առավելություններն ու առանձնահատկությունները DI-ի:
- Պատասխանատվության բաժանում: Կլասը չի կրում իր կախվածությունների ստեղծման պատասխանատվությունը:
- Թեստավորման հեշտություն: Կողմից փոխարինվում են մոկերով կամ սաղմերով մոդուլային թեստավորման ժամանակ:
- Գնահատելիություն: Լավ է փոխել կախվածությունների իրականացմանը առանց կոդի փոփոխության:
- Փոքր կապակցվածություն: Կոմպոնենտները դառնում են ավելի քիչ կապված, ինչը բարելավում է սպասարկումը:
Ներգրավման եղանակներ:
-
Կոնստրուկտորով (Constructor Injection): Կախվածությունները փոխանցվում են կոնստրուկտորով։ Սա ամենալավ տարբերակն է, քանի որ ապահովում է կախվածությունների առկայությունը օբյեկտի ստեղծման պահին։
// Կլաս կախվածությամբ public class MyService { private MyDependency dependency; // Ներգրավում կոնստրուկտորով public MyService(MyDependency dependency) { this.dependency = dependency; } // Կիրառում կախվածությունը public void doSomething() { dependency.performAction(); } } // Կախվածություն public interface MyDependency { void performAction(); } // Կախվածության իրականացման օրինակ public class MyDependencyImpl implements MyDependency { @Override public void performAction() { System.out.println("Action performed!"); } } -
Սեթերով (Setter Injection): Կախվածությունները փոխանցվում են հանրային մեթոդներով։ Սա թույլ է տալիս ստեղծել օբյեկտներ կախվածություններով ըստ պահանջի, բայց պահանջում է լրացուցիչ ստուգումներ null-ի համար և չի երաշխավորում բոլոր կախվածությունների առկայությունը։
// Կլաս կախվածությամբ public class AnotherService { private AnotherDependency dependency; // Դատարկ կոնստրուկտոր public AnotherService() { } // Ներգրավում սեթերով public void setDependency(AnotherDependency dependency) { this.dependency = dependency; } // Կիրառում կախվածությունը public void doSomethingElse() { if (dependency != null) { dependency.anotherAction(); } else { System.out.println("Dependency is not set!"); } } } // Կախվածություն public interface AnotherDependency { void anotherAction(); } // Կախվածության իրականացման օրինակ public class AnotherDependencyImpl implements AnotherDependency { @Override public void anotherAction() { System.out.println("Another action performed!"); } } -
Մայդանով (Field Injection): Կախվածությունները անմիջապես ներմուծվում են դասի դաշտեր՝ օգտագործելով նշումներ։ Սա ամենահեշտն է գրելու, բայց դարձնում է դասը կախված DI-ֆրեյմվորկից և դժվարացնում է թեստավորումը առանց ֆրեյմվորկի։
import org.springframework.beans.factory.annotation.Autowired; // Կլաս կախվածությամբ public class SomeOtherService { // Ներգրավում դաշտով (օգտագործելով Spring նշում) @Autowired private YetAnotherDependency dependency; // Կիրառում կախվածությունը public void doYetAnotherThing() { dependency.performYetAnotherAction(); } } // Կախվածություն public interface YetAnotherDependency { void performYetAnotherAction(); } // Կախվածության իրականացման օրինակ public class YetAnotherDependencyImpl implements YetAnotherDependency { @Override public void performYetAnotherAction() { System.out.println("Yet another action performed!"); } }
Համեմատություն՝
| Ներգրավման եղանակը | Առավելություններ | Թերություններ |
|---|---|---|
| Կոնստրուկտորով | Գаранտիա է տալիս, որ կախվածությունները առկա են, հեշտ է թեստավորել, անփոփոխելի | Կարող է առաջացնել "պարամետրային կախվածություն" կոնստրուկտորում՝ մեծ քանակությամբ կախվածությունների դեպքում |
| Սեթերով | Ընտրական կախվածություններ, հնարավոր է փոփոխել կախվածությունները ստեղծելուց հետո | Պահանջում է null ստուգումներ, չի երաշխավորում օբյեկտի ամբողջական վիճակը ստեղծելուց հետո |
| Մայդանով | Կարճ սինտաքսիս | Կախված է DI-ֆրեյմվորկից, դժվարացնում է թեստավորումը առանց ֆրեյմվորկի |
DI-ը հիմնական սկզբունք է շատ ժամանակակից ֆրեյմվորկներում (օրինակ՝ Spring, CDI) և նպաստում է թույլ կապակցված և հեշտ թեստավորվող ծրագրերի ստեղծմանը։