Dependency Injection
λ³Έ κΈμ μ κ° NestJS
νλ μ μν¬λ₯Ό ν΅ν΄ κ°λ°νλ©΄μ κΉ¨λ¬μ λ
Ένμ°λ₯Ό κΈ°λ‘ν κ²μ
λλ€. μ κ° μ μν λ°©λ²λ³΄λ€ λ μ’μ λ°©λ²μ΄ μμ μλ μμ΅λλ€. μ§μ μ μΈμ λ νμμ
λλ€ :)
Dependency Injectionμ NestJS
νλ μμν¬μμ λ¨κ³¨λ‘ λ±μ₯νλ μ©μ΄λ€.
Dependency Injection(DI)λ μνμ¨μ΄ μ€κ³μ βDesign Patternβ μ€ νλλ€.
DIλ βμμ‘΄μ±(Dependency)βκ³Ό βμ£Όμ (Injection)βμ ν¨κ» μ¬μ©νλ μ€κ³ λ°©λ²μ΄λ€. κ·Έλμ λ κ°λ μ λν μ΄ν΄κ° μ νλμ΄μΌ νλ€!
λ³ΈνΈμ λ€μ΄κ°κΈ° μ μ DIμ λν κ°λ¨ν 지μ λ³΄κ³ κ°μ π
Material from here
μμ‘΄μ±; Dependency
Β βDependency is a relationship between components or classes that can be thought of as a βusesβ relationship.β
Class $A$ uses Class $B$
$\equiv$
Class $A$ is dependent on Class $B$
$\equiv$
Class $B$ is a dependency of Class $A$
μ§κ΄μ μΌλ‘ λ§νλ©΄ Class $A$κ° Class $B$λ₯Ό λ΄λΆ λ³μλ‘ κ°μ§λ€κ³ λ§ν μ μμ κ² κ°λ€.
μ΄λ²μ μ½λ λ 벨μμ μ΄ν΄λ³΄μ!
public class PetOwner{
private AnimalType animal;
public PetOwner() {
this.animal = new Dog();
}
}
// code fragment from here
μ΄ μ½λμμ PetOwner
κ°μ²΄λ AnimalType
μ κ°μ²΄λ₯Ό λ§λ€κΈ° μν΄ Dog
κ°μ²΄μ βμμ‘΄βνλ€.
μννΈμ¨μ΄λ₯Ό λ§λλ κ³Όμ μμ βμμ‘΄μ±βμ νΌν μ μλ€! (μμ‘΄μ± μλ μννΈμ¨μ΄κ° μ΄λ μκ² λκ°)
νμ§λ§, PetOwner
μ Dog
μ¬μ΄μμλ PetOwner
κ° μ¬μ©ν animal
μ΄λΌλ κ°μ²΄ μμ±κ³Ό κΈ°λ₯μ΄ λͺ¨λ Dog
μ μμ‘΄νλ€. μ¦, μμ£Ό κΈ΄λ°νκ² μ°κ²°(tight coupling) λμ΄ μλ€κ³ λ³Ό μ μλ€.
μ΄λ° μν©μ λμμΈ ν¨λ¬λ€μ μ€ νλμΈ βLow Couplingβμ λΆν©νμ§ μλλ€.
μλνλ©΄, Couplingμ΄ μ‘΄μ¬νλ€λ©΄ μ΄λ€ λͺ¨λμ APIλ νλμ΄ λ°λλ€λ©΄, κ·Έ λͺ¨λμ μμ‘΄ν λ€λ₯Έ λͺ¨λκΉμ§ μ½λλ₯Ό λ³κ²½ν΄μ€μΌ ν κ°λ₯μ±μ΄ μκΈ°κΈ° λλ¬Έμ΄λ€.
μ¦, Dog
κ°μ²΄λ₯Ό μμ νλ©΄, PetOwner
κΉμ§ λ©λ¬μ μμ ν΄μΌ ν μ§λ λͺ¨λ₯Έλ€.
μ£Όμ ; Injection
βμ£Όμ βμ κ°μ²΄ μμ±μ΄ λ΄λΆκ° μλλΌ βμΈλΆβμμ μ§ννμ¬ κ·Έκ²μ μ¬μ©ν κ°μ²΄μ μ£Όμ νλ κ²μ λ§νλ€.
μμ μμ μ½λμμλ this.animal
κ°μ²΄μ μμ±μ PetOwner
κ°μ²΄μ βλ΄λΆβμμ μ§ννλ€.
κ·Έλμ μ΄λ²μ βμ£Όμ βμΌλ‘ μ½λλ₯Ό μμ ν΄λ³΄μ.
public class PetOwner{
private AnimalType animal;
public PetOwner(AnimalType animal) {
this.animal = animal;
}
}
μμ μ΄νμλ PetOwner
μ μμ±μμμ animal
μ λν μΈμλ₯Ό λ°λ λ°©μμΌλ‘ λ°λμλ€.
μ΄λ κ°μ²΄ λ΄λΆκ° μλ βμΈλΆβμμ AnimalType
μ κ°μ²΄μ λ§λ€μ΄ PetOwner
κ°μ²΄μ μ£Όμ
νλ κΌ΄μ΄λ€!
μ΄λ κ² λ§λ€ κ²½μ°, PetOwner
μ Dog
μ¬μ΄μ coupingμ μ
μ΄μ§κ² λλ€!!
μ€νλ € Dog
λμ μ Cat
μ΄λ Rabbit
κ°μ μλ‘μ΄ ννμ AniamlType
ν΄λμ€λ₯Ό μ μ ν΄μ€ μ μλ€!! (짱μΈλ°?)
μ¬μ€ μμ κ°μ΄ βμμ‘΄μ±βμ΄ λ°κ²¬λλ λΆλΆμ βμ£Όμ βμΌλ‘ ν΄κ²°ν΄μ£Όλ©΄ βμμ‘΄μ±-μ£Όμ βμ΄ λλ€!! π
μμ μ½λμμλ κ°λ¨νκ² ν¨μ μΈμλ‘ μ€μ νμ§λ§, κ°μ²΄λ₯Ό μμ±μ Factory
λ₯Ό μ¬μ©ν μλ μμ κ² κ°λ€!!
μ¬κΈ°κΉμ§λ§ μλ©΄, DIμ λν΄ μΆ©λΆν μ΄ν΄ν κ²μ΄λ€.
μ΄μ μ‘°κΈ μννΈμ¨μ΄ μ€κ³λ₯Ό κ³λ€μΈ κ°λ λ€μ μ΄ν΄λ³΄μ. Design Principleμ λν΄ μ΅μνλ€λ©΄, λΉμ°ν κ²λ€μ κΈ°μ νλ κ²κ³Ό λΆκ³Όνλ€κ³ λλ κ²μ΄λ€.
μ μ΄μ μμ κ³Ό μμ‘΄κ΄κ³ μμ
μ μ΄μ μμ
Β Principle that promotes components that relinquish control of aspects of the code execution to external modules to obtain βweek couplingβ. * relinquish: give up
</div>
μλ₯Ό λ€μ΄, Sorting ν¨μμ Comparatorκ° λνμ μΈ βμ μ΄μ μμ (Inversion of Control; IoC)βμ΄λ€!
List<T>.Sort(IComparator<T>);
Listμ Sort
ν¨μλ μ€μ Sortingμ μνν ꡬ체μ μΈ λ°©λ²/κΈ°μ€μ Sort APIλ₯Ό μ¬μ©νλ Client λ¨μμ 맑κΉμΌλ‘μ¨ Controlμ μΌλΆλ₯Ό ν¬κΈ°νμλ€!
Clientλ IComparator
dependencyμ λν implementation, creation, lifetimeμ λͺ¨λ μ§μ κ΄λ¦¬νλ€!
μ΄ βμ μ΄μ μμ βκ³Ό DIμ λν κ΄κ³λ μλ λ¬Έμ₯μμ μκ°λλ€.
Β βDependency injection is a software design pattern that implements inversion of control for resolving dependencies. A βdependencyβ is an object that can be used. An βinjectionβ is the passing of a dependency to a dependent object that would use it. - Wikipedia
</div>
μμ‘΄κ΄κ³ μμ μ μμΉ
βμμ‘΄κ΄κ³ μμ μ μμΉ(Dependency Inversion Principle; DIP)βλ κ°μ²΄ μ¬μ΄μ μμ‘΄κ΄κ³λ₯Ό λ§Ίμ λμ κ°μ΄λ λΌμΈμ΄λ€.
DIPλ μμ‘΄κ΄κ³λ₯Ό λ§Ίμ λ λ³ννκΈ° μ¬μ΄ κ² λλ μμ£Ό λ³νλ κ² λ³΄λ€λ λ³ννκΈ° μ΄λ €μ΄ κ², κ±°μ λ³νμ§ μλ κ²μ μμ‘΄νλΌλ μμΉμ΄λ€!
μ΄λ, λ³ν¨μ λν κ΅¬λΆ κΈ°μ€μ
- μ€κ³λ
interface
μ΄λ©΄ λ³νμ§ μλ κ², μμ§ λ³νμ§ μμ κ² - ꡬν체
implementation
μ μ΄λ―Έ λ³ν κ²
μ λλ‘ μ΄ν΄νλ©΄ λ κ² κ°λ€.
μμμμ μμ λ₯Ό λΉλ €μ€μλ©΄, ꡬνμ²΄μΈ Dog
μ μμ‘΄νλ κ²μ΄ μλλΌ AnimalType
μ체μ κ°μ μΆμμ μΈ interface
μ μμ‘΄νλΌλ κ²μ΄λ€!!
interface
μ μμ‘΄ν¨μΌλ‘μ¨ μννΈμ¨μ΄λ μ’λ μ μ°ν μμ€ν
μ΄ λλ€.
μ’λ μλ°ν κΈ°μ ν΄λ³΄μλ©΄,
A. νμ΄-λ 벨 λͺ¨λμ λ‘μ°-λ 벨 λͺ¨λμ μμ‘΄ν΄μλ μ λλ€. λλ€ μΆμμ μμ‘΄ν΄μΌ νλ€.
A. High-level module should not depend upon low-level module. Both should depend upon abstractions.
B. μΆμμ μμΈλ₯Ό μμ‘΄ν΄μλ μ λλ€. μμΈλ μΆμμ μμ‘΄ν΄μΌ νλ€.
B. Abstractions should not depend upon details. Details should depend upon abstraction.
βμμ‘΄ κ΄κ³ μμ βμμ βμμ inversionβμ μλ―Έλ λͺ¨λ κ²μ λ‘μ°-λ 벨 λͺ¨λμ μμ‘΄νλ μ ν΅μ μΈ μ€κ³μμ νμ΄-λ 벨 λͺ¨λμ μμ‘΄νλ λ°©μμΌλ‘ βμμ βλμλ€λ μλ―Έλ₯Ό λ΄κ³ μλ€.
λͺ¨λΈ λμμΈμ΄ DIPλ₯Ό λ§μ‘±νλ μ€κ³λΌλ©΄, βμμ‘΄μ± μ£Όμ βμ μ½κ² μμ©νλ μ½λλ₯Ό μμ±ν μ μλ€.
μμ‘΄μ±μ΄ νμν λΆλΆμ΄ implementation
μ΄ μλλΌ interface
μ μμ‘΄λμ΄ μκΈ° λλ¬Έμ κ·Έ interface
λ₯Ό κΈ°λ°μΌλ‘ νλ€λ©΄ μμ‘΄μ±μ μμ½κ² μ£Όμ
ν μ μλ€.
μ! μ΄μ μ²μμ λ΄€λ 지μ λ€μ νλ² λ³΄μ.
Material from here