CS/Algorithm
📌 객체지향 프로그래밍(OOP), SOLID 원칙, 디자인 패턴, DI - TypeScript 예제 포함 상세 설명
nkm
2025. 2. 2. 20:23
728x90
반응형
1. 객체지향 프로그래밍 (OOP)
객체(Object)를 중심으로 설계하는 프로그래밍 패러다임으로, 캡슐화, 상속, 다형성, 추상화를 기반으로 함.
1.1 OOP의 4대 원칙
원칙 | 설명 | TypeScript 적용 |
---|---|---|
캡슐화 (Encapsulation) | 데이터를 외부에서 직접 접근하지 못하게 하고, 메서드를 통해 조작 | private 또는 protected 키워드 사용 |
상속 (Inheritance) | 부모 클래스의 속성과 메서드를 자식 클래스가 재사용 | extends 키워드 사용 |
다형성 (Polymorphism) | 같은 인터페이스/부모 클래스를 공유하는 객체들이 서로 다른 동작을 할 수 있도록 함 | interface 또는 abstract class 활용 |
추상화 (Abstraction) | 불필요한 세부사항을 숨기고, 중요한 부분만 노출 | abstract class 사용 |
🔹 TypeScript 예제 (OOP 적용)
// ✅ 1️⃣ 캡슐화: private 사용
class User {
private password: string;
constructor(public username: string, password: string) {
this.password = password;
}
authenticate(inputPassword: string): boolean {
return this.password === inputPassword;
}
}
// ✅ 2️⃣ 상속: extends 사용
class Admin extends User {
constructor(username: string, password: string, public role: string) {
super(username, password);
}
}
// ✅ 3️⃣ 다형성: interface 사용
interface Animal {
makeSound(): void;
}
class Dog implements Animal {
makeSound() {
console.log("멍멍!");
}
}
class Cat implements Animal {
makeSound() {
console.log("야옹!");
}
}
// ✅ 4️⃣ 추상화: abstract class 사용
abstract class Vehicle {
abstract start(): void;
}
class Car extends Vehicle {
start() {
console.log("🚗 시동을 겁니다.");
}
}
2. SOLID 원칙
객체지향 설계를 더욱 견고하고 유지보수하기 쉽게 만드는 5가지 원칙.
2.1 SOLID 원칙 설명 및 TypeScript 적용
✅ 2.1.1 SRP (단일 책임 원칙)
"하나의 클래스는 하나의 책임(기능)만 가져야 한다."
// ❌ 잘못된 예제 (SRP 위반)
class User {
saveToDatabase() { /* DB 저장 로직 */ }
sendEmail() { /* 이메일 발송 로직 */ }
}
// ✅ 올바른 예제 (SRP 적용)
class UserRepository {
saveToDatabase() { /* DB 저장 */ }
}
class EmailService {
sendEmail() { /* 이메일 발송 */ }
}
✅ 2.1.2 OCP (개방-폐쇄 원칙)
"기존 코드를 수정하지 않고 확장할 수 있어야 한다."
// ❌ OCP 위반: 새로운 결제 방식이 추가될 때마다 if-else를 수정해야 함.
class PaymentService {
processPayment(type: string, amount: number) {
if (type === "credit") {
console.log(`💳 ${amount}원 신용카드 결제`);
} else if (type === "paypal") {
console.log(`💻 ${amount}원 PayPal 결제`);
}
}
}
// ✅ OCP 적용: 새로운 결제 방식이 추가되어도 기존 코드 수정이 필요 없음
interface PaymentStrategy {
pay(amount: number): void;
}
class CreditCardPayment implements PaymentStrategy {
pay(amount: number): void {
console.log(`💳 ${amount}원 신용카드 결제`);
}
}
class PaypalPayment implements PaymentStrategy {
pay(amount: number): void {
console.log(`💻 ${amount}원 PayPal 결제`);
}
}
class Order {
constructor(private payment: PaymentStrategy) {}
checkout(amount: number) {
this.payment.pay(amount);
}
}
3. 디자인 패턴
디자인 패턴은 소프트웨어 설계에서 반복적으로 사용되는 해결책이다.
✅ 3.1 Factory 패턴
객체 생성을 담당하는 클래스를 따로 두어 생성 과정을 캡슐화
class AnimalFactory {
static createAnimal(type: string): Animal {
if (type === "dog") {
return new Dog();
} else {
return new Cat();
}
}
}
const myPet = AnimalFactory.createAnimal("dog");
myPet.makeSound();
✅ 3.2 Singleton 패턴
하나의 인스턴스만 유지하는 패턴
class Singleton {
private static instance: Singleton;
private constructor() {}
static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
✅ 3.3 Builder 패턴
객체 생성 시 필수 매개변수와 선택적 매개변수를 유연하게 설정
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();
4. 의존성 주입 (DI - Dependency Injection)
클래스가 직접 의존성을 생성하지 않고, 외부에서 주입받도록 설계
interface Database {
connect(): void;
}
class MySQLDatabase implements Database {
connect(): void {
console.log("MySQL 데이터베이스 연결됨");
}
}
class UserService {
constructor(private db: Database) {}
getUser() {
this.db.connect();
console.log("사용자 정보 가져오기");
}
}
const userService = new UserService(new MySQLDatabase());
userService.getUser(); // MySQL 데이터베이스 연결됨
🚀 결론
✔ OOP → 객체지향 개념을 적용하여 코드의 재사용성과 유지보수성을 높임
✔ SOLID 원칙 → 좋은 코드 설계를 위한 필수 원칙 적용
✔ 디자인 패턴 → Factory, Singleton, Builder 패턴 등을 활용하여 유연한 코드 작성
✔ DI (의존성 주입) → 객체 간 결합도를 낮춰 유지보수성과 확장성을 높임
TypeScript를 활용한 객체지향 설계를 마스터하면 더 효율적인 코드 작성이 가능하다! 🚀🔥
728x90
반응형