의존성 주입 Dependency Injection으로 약칭 DI
라고 부른다.
의존성(의존관계, 의존)
객체가 자신의 기능을 수행하기 위해 필요한 다른 객체나 구성 요소
주입
객체가 필요한 의존성을 외부에서 제공받는 과정
의존성 주입
객체가 자신의 기능을 수행하기 위해 필요한 다른 객체나 구성 요소를 외부에서 제공받는 과정
컴포넌트를 드래그 드롭으로 스크립트에 연결하는 것도 넓은 의미에서 의존성 주입
위 그림은 attack 메서드가 baseAttack 메서드 한개만 의존하고 있지만, 코드가 늘어날수록
의존하게 되는 메서드가 많아지면서 유지보수가 어려워진다.
BaseAttack Button을 눌렀을 땐 baseAttack이 출력되고, SpecialAttack Button을 눌렀을 땐 Special Attack이 출력되며, MagicAttack Button을 눌렀을 땐 MagicAttack이 출력되는 형식의 코드이다.
위 방식처럼 interface
를 활용하여 코드의 가독성을 높이고, 유지보수성을 높일 수 있다.
필드에 직접 필요한 의존성을 주입하는 방식이다.
간단하여 쓰기는 편하지만 나중에 유지보수를 할 때 문제가 발생할 수 있다.
메서드로 필요한 의존성을 주입
추천하는 방법중 하나
단점 : 의존성 주입을 위해 필요 없는 메서드 하나를 만들어야 한다는 단점이 있다.
프로퍼티로 필요한 의존성을 주입
set
키워드를 이용하여 의존성을 주입할 수 있다.
유지보수에도 좋다.
가급적으론 프로퍼티 주입 방식을 사용하는 것이 좋다.
- Single Responsibility Principle
- Open/Closed Principle
- Liskov Substitution Principle
- Interface Segregation Principle
- Dependency Inversion Principle
단일 책임 원칙(SRP, Single Responsibility Principle)
클래스, 모듈, 함수는 하나의 책임만 가져야 하며, 변경 이유도 하나여야 한다.
- EX) 플레이어 클래스는 플레이어에 관한 책임만 가지고 있어야 하고 다른 코드의 책임을 가지면 안된다.
개방 폐쇠 원칙(OCP, Open/Closed Principle)
소프트웨어 요소는 확장에는 열려 있지만, 수정에는 닫혀 있어야 한다.
즉 새로운 기능을 추가할 때 기존 코드를 변경하지 않고도 가능해야 한다.
- EX) 기존 코드를 변경하지 않고 기능을 추가해야 한다.
리스코프 치환 원칙(LSP, Liskov Substitution Principle)
자식 클래스는 부모 클래스의 역할을 대체할 수 있어야 한다.
이는 상속구조에서 일관성을 유지하는데 중요하다.
- EX) 부모 클래스를 사용하는 코드에서 자식 클래스를 사용하더라도, 기존의 동작이 변하지 않아야 한다. 자식 클래스가 부모 클래스의 특성을 잘 유지하고 있어야만, 코드의 일관성도 유지된다.
인터페이스 분리 원칙(ISP, Interface Segregation Principle)
특정 클라이언트를 위한 인터페이스는 범용 인터페이스보다 더 유용해야 한다.
사용하지 않는 메서드에 의존하지 않도록 인터페이스를 작게 분리하는 것이 좋다.
- EX) 인터페이스가 여러개의 메서드를 가지고 있지 않고 각각의 인터페이스로 분리해놓으라는 것
의존성 역전 원칙(DIC, Dependency Inversion Principle)
고수준의 모듈은 저수준의 모듈에 의해 의존해서는 안되며, 두 모듈 모두
추상화에 의존해야 한다.
이를 통해 시스템의 유연성과 재사용성을 높일 수 있다.
EX) 두 모듈은 추상화에 의존해야 된다는 것. 서로 직접적으로 연결되면 안된다는 것.