728x90
반응형
📌 디자인 패턴 (Design Patterns) – TypeScript로 상세 정리
디자인 패턴은 자주 발생하는 소프트웨어 설계 문제를 해결하기 위한 일반적인 해결책이다.
유지보수성과 확장성이 뛰어난 코드를 작성하는 데 도움을 준다.
1. 디자인 패턴 개요
디자인 패턴은 3가지 주요 유형으로 분류된다.
패턴 유형 설명 대표 패턴
생성(Creational) 패턴 | 객체 생성 방법을 최적화 | Singleton, Factory, Builder |
구조(Structural) 패턴 | 클래스나 객체의 구조를 조정하여 효율적인 설계 제공 | Adapter, Decorator, Facade |
행동(Behavioral) 패턴 | 객체 간의 상호작용을 최적화 | Observer, Strategy, Command |
2. 생성(Creational) 패턴
객체를 효율적으로 생성하고 관리하는 패턴.
인스턴스를 직접 생성하는 대신, 유연하게 객체를 생성할 수 있도록 한다.
2.1 Singleton 패턴
"한 클래스의 인스턴스가 하나만 존재하도록 제한하는 패턴"
- 전역 상태 관리에 유용 (예: 설정 정보, 데이터베이스 연결)
✅ Singleton 패턴 예제
class Singleton {
private static instance: Singleton;
private constructor() {} // 외부에서 인스턴스 생성을 방지
static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
showMessage(): void {
console.log("🟢 Singleton 인스턴스입니다!");
}
}
// 사용법
const obj1 = Singleton.getInstance();
const obj2 = Singleton.getInstance();
console.log(obj1 === obj2); // ✅ true (같은 인스턴스)
obj1.showMessage(); // 🟢 Singleton 인스턴스입니다!
📌 활용 예시
- 데이터베이스 연결 객체
- 애플리케이션 설정 객체
2.2 Factory 패턴
"객체 생성을 서브클래스에서 수행하도록 위임하여 코드의 유연성을 높이는 패턴"
- 클라이언트 코드가 직접 객체를 생성하지 않고, 팩토리 메서드를 통해 생성.
✅ Factory 패턴 예제
// 공통 인터페이스
interface Animal {
makeSound(): void;
}
// 구체적인 클래스
class Dog implements Animal {
makeSound() {
console.log("🐶 멍멍!");
}
}
class Cat implements Animal {
makeSound() {
console.log("🐱 야옹!");
}
}
// 팩토리 클래스
class AnimalFactory {
static createAnimal(type: string): Animal {
if (type === "dog") {
return new Dog();
} else {
return new Cat();
}
}
}
// 사용법
const myPet = AnimalFactory.createAnimal("dog");
myPet.makeSound(); // 🐶 멍멍!
📌 활용 예시
- 데이터베이스 연결 객체 생성
- UI 컴포넌트 동적 생성
2.3 Builder 패턴
"복잡한 객체 생성을 단계적으로 수행하는 패턴"
- 생성자의 인자가 많을 때, 가독성과 유지보수성을 높인다.
✅ Builder 패턴 예제
class Car {
constructor(
public brand: string,
public model: string,
public color?: string
) {}
}
class CarBuilder {
private brand!: string;
private model!: string;
private color?: string;
setBrand(brand: string): CarBuilder {
this.brand = brand;
return this;
}
setModel(model: string): CarBuilder {
this.model = model;
return this;
}
setColor(color: string): CarBuilder {
this.color = color;
return this;
}
build(): Car {
return new Car(this.brand, this.model, this.color);
}
}
// 사용법
const myCar = new CarBuilder().setBrand("Tesla").setModel("Model S").setColor("Red").build();
console.log(myCar);
📌 활용 예시
- 데이터베이스 쿼리 생성
- 복잡한 UI 컴포넌트 생성
3. 구조(Structural) 패턴
"클래스나 객체의 구조를 조정하여 효율적인 설계를 제공하는 패턴"
3.1 Adapter 패턴
"서로 다른 인터페이스를 가진 클래스를 연결하는 패턴"
- 기존 클래스를 수정하지 않고 다른 인터페이스와 호환 가능.
✅ Adapter 패턴 예제
class LegacyPrinter {
printMessage(): void {
console.log("🖨️ 레거시 프린터 출력 중...");
}
}
// 새로운 인터페이스
interface NewPrinter {
print(): void;
}
// 어댑터 클래스
class PrinterAdapter implements NewPrinter {
constructor(private legacyPrinter: LegacyPrinter) {}
print(): void {
this.legacyPrinter.printMessage();
}
}
// 사용법
const oldPrinter = new LegacyPrinter();
const printer = new PrinterAdapter(oldPrinter);
printer.print(); // 🖨️ 레거시 프린터 출력 중...
📌 활용 예시
- 레거시 코드와 새로운 코드의 호환성 유지
- API 통합 및 변환
3.2 Decorator 패턴
"기능을 동적으로 추가할 수 있도록 하는 패턴"
- 상속 없이 객체의 기능을 확장할 수 있다.
✅ Decorator 패턴 예제
interface Coffee {
getDescription(): string;
cost(): number;
}
class BasicCoffee implements Coffee {
getDescription(): string {
return "기본 커피";
}
cost(): number {
return 3000;
}
}
class MilkDecorator implements Coffee {
constructor(private coffee: Coffee) {}
getDescription(): string {
return this.coffee.getDescription() + ", 우유 추가";
}
cost(): number {
return this.coffee.cost() + 500;
}
}
// 사용법
const myCoffee = new MilkDecorator(new BasicCoffee());
console.log(myCoffee.getDescription()); // 기본 커피, 우유 추가
console.log(myCoffee.cost()); // 3500원
📌 활용 예시
- UI 컴포넌트 기능 추가
- 미들웨어 패턴 (예: Express.js)
4. 행동(Behavioral) 패턴
"객체 간의 상호작용을 최적화하는 패턴"
4.1 Observer 패턴
"한 객체의 상태 변화가 다른 객체들에게 자동으로 전달되도록 하는 패턴"
- 이벤트 리스너 같은 역할을 한다.
✅ Observer 패턴 예제
interface Observer {
update(message: string): void;
}
class User implements Observer {
constructor(private name: string) {}
update(message: string): void {
console.log(`${this.name}님, 알림: ${message}`);
}
}
class NewsChannel {
private observers: Observer[] = [];
subscribe(observer: Observer): void {
this.observers.push(observer);
}
notify(message: string): void {
this.observers.forEach(observer => observer.update(message));
}
}
// 사용법
const user1 = new User("Alice");
const user2 = new User("Bob");
const news = new NewsChannel();
news.subscribe(user1);
news.subscribe(user2);
news.notify("새 뉴스가 도착했습니다!");
📌 활용 예시
- 이벤트 시스템 (예: DOM 이벤트 리스너)
- Pub-Sub 시스템
🚀 결론
✔ 디자인 패턴을 적용하면 유지보수성과 확장성이 뛰어난 코드 작성 가능!
✔ 생성, 구조, 행동 패턴을 이해하고 실무에 활용하면 코드 품질 향상!
🔥 다음 단계 → 의존성 주입(DI) 자세히 설명! 🚀
728x90
반응형
'CS > Algorithm' 카테고리의 다른 글
📌 의존성 주입(DI - Dependency Injection) 자세히 설명 🚀 (1) | 2025.02.03 |
---|---|
📌 SOLID 원칙 – 객체지향 프로그래밍의 핵심 설계 원칙 (0) | 2025.02.02 |
📌 객체지향 프로그래밍(OOP) - TypeScript로 자세히 정리 (0) | 2025.02.02 |
📌 객체지향 프로그래밍(OOP), SOLID 원칙, 디자인 패턴, DI - TypeScript 예제 포함 상세 설명 (0) | 2025.02.02 |
[CS] Typescript를 활용한 자료구조 중 Array, LinkedList (1) | 2024.12.19 |