1. 의존성 주입 (Dependency Injection)
TypeScript
// 1. 의존성 인터페이스 정의
interface ILogger {
log(message: string): void;
}
// 2. 구체적인 구현 클래스
class ConsoleLogger implements ILogger {
log(message: string) {
console.log(`[Console] ${message}`);
}
}
// 3. 의존성을 주입받는 클래스
class UserManager {
constructor(private logger: ILogger) {}
createUser(name: string) {
this.logger.log(`User ${name} created`);
}
}
// 4. 의존성 주입
const logger = new ConsoleLogger();
const userManager = new UserManager(logger);
userManager.createUser("Alice");
JavaScript (ES6)
// 1. 구체적인 구현 클래스
class ConsoleLogger {
log(message) {
console.log(`[Console] ${message}`);
}
}
// 2. 의존성을 주입받는 클래스
class UserManager {
constructor(logger) {
this.logger = logger;
}
createUser(name) {
this.logger.log(`User ${name} created`);
}
}
// 3. 의존성 주입
const logger = new ConsoleLogger();
const userManager = new UserManager(logger);
userManager.createUser("Alice");
Python
from abc import ABC, abstractmethod
# 1. 의존성 추상 클래스
class ILogger(ABC):
@abstractmethod
def log(self, message: str) -> None:
pass
# 2. 구체적인 구현 클래스
class ConsoleLogger(ILogger):
def log(self, message: str) -> None:
print(f"[Console] {message}")
# 3. 의존성을 주입받는 클래스
class UserManager:
def __init__(self, logger: ILogger):
self.logger = logger
def create_user(self, name: str) -> None:
self.logger.log(f"User {name} created")
# 4. 의존성 주입
logger = ConsoleLogger()
user_manager = UserManager(logger)
user_manager.create_user("Alice")
2. 의존성 역전 원칙 (Dependency Inversion Principle)
TypeScript
// 1. 추상화 계층 (고수준 모듈)
interface ILogger {
log(message: string): void;
}
// 2. 저수준 모듈 (구체적 구현)
class ConsoleLogger implements ILogger {
log(message: string) {
console.log(`[Console] ${message}`);
}
}
class FileLogger implements ILogger {
log(message: string) {
// 파일 저장 로직
console.log(`[File] ${message}`);
}
}
// 3. 고수준 모듈 (추상화에 의존)
class UserManager {
constructor(private logger: ILogger) {}
createUser(name: string) {
this.logger.log(`User ${name} created`);
}
}
// 4. 의존성 주입으로 구현 선택
const userManager = new UserManager(new FileLogger());
userManager.createUser("Bob");
3. 제어 역전 (Inversion of Control)
TypeScript (간단한 IoC 컨테이너)
// 1. IoC 컨테이너
class Container {
private static dependencies: { [key: string]: any } = {};
static register(key: string, dependency: any) {
this.dependencies[key] = dependency;
}
static resolve<T>(key: string): T {
return this.dependencies[key];
}
}
// 2. 의존성 등록
Container.register("logger", new ConsoleLogger());
Container.register("userManager", new UserManager(Container.resolve("logger")));
// 3. 의존성 사용
const userManager = Container.resolve<UserManager>("userManager");
userManager.createUser("Charlie");
Python (간단한 IoC 컨테이너)
class Container:
_dependencies = {}
@classmethod
def register(cls, key, dependency):
cls._dependencies[key] = dependency
@classmethod
def resolve(cls, key):
return cls._dependencies.get(key)
# 의존성 등록
Container.register("logger", ConsoleLogger())
Container.register("user_manager", UserManager(Container.resolve("logger")))
# 의존성 사용
user_manager = Container.resolve("user_manager")
user_manager.create_user("Charlie")
4. 핵심 원리 요약
개념
|
설명
|
예시
|
의존성 주입 (DI)
|
외부에서 의존 객체를 전달받아 결합도를 낮춥니다.
|
TypeScript, JavaScript, Python
|
의존성 역전 (DIP)
|
고수준 모듈이 저수준 모듈에 의존하지 않고, 추상화에 의존하도록 설계합니다.
|
Interface/Abstract Class 사용
|
제어 역전 (IoC)
|
객체 생성/관리를 외부 컨테이너에 위임해 제어 흐름을 역전시킵니다.
|
IoC 컨테이너 구현 (TypeScript 예시)
|