의존성 주입이란 무엇인가?
의존성 주입을 해야 하는 이유는 무엇일까요?
아래 코드는 객체를 직접 의존성을 생성하여 코드의 결합도가 높습니다. 때문에 코드의 유연성도 낮고 확장성에서 불리한 코드 입니다.
export class MessagesService {
messagesRepository: MessageRepository;
constructor() {
this.messagesRepository = new MessageRepository();
}
}
이 코드를 다음과 같이 수정합니다.
이 코드에서는 자체 의존성을 생성하도록 하는 것이 아닌, 생성자에 인수로 의존성 주입하도록 설정합니다.
export class MessagesService {
messagesRepository: MessageRepository;
constructor(repo: MessageRepository) {
this.messagesRepository = repo;
}
}
하지만 MessageRepository는 MessagesService클래스에 의존하는 존재입니다.
의존성을 분리하기 위해서는 인터페이스 기반 프로그래밍을 해야 합니다.
Repository
인터페이스를 정의를 합니다. Repository 인터페이스를 객체로 제공하여 다른 클래스를 직접 참조하지 않고도 기능을 활용 할 수 있습니다.
interface Repository {
findOne(id: string);
findAll();
create(content: string);
}
export class MessagesService {
messagesRepository: Repository;
constructor(repo: Repository) {
this.messagesRepository = repo;
}
}
class InMemoryMessageRepository implements MessageRepository {
private readonly messages: Message[] = [];
async findOne(id: string): Promise<Message> {
return this.messages.find((message) => message.id === id);
}
async findAll(): Promise<Message[]> {
return this.messages;
}
async create(content: string): Promise<Message> {
const message = new Message(content);
this.messages.push(message);
return message;
}
}
위 코드에서 MessagesService는 MessageRepository 인터페이스에 의존하지만, 구체적인 MessageRepository 구현은 InMemoryMessageRepository 클래스를 사용합니다.
이처럼 의존성 주입을 통해 코드 간의 결합도를 낮추고 유연성을 높일 수 있습니다.