SOLID & OOP 디자인 비즈니스 케이스

발행: (2026년 1월 20일 오후 09:54 GMT+9)
7 min read
원문: Dev.to

Source: Dev.to

위에 제공된 소스 링크 외에 번역할 텍스트를 알려주시면 한국어로 번역해 드리겠습니다.

Source:

OOP 설계 원칙

캡슐화

캡슐화는 데이터를 해당 데이터를 조작하는 메서드와 함께 묶고, 객체의 일부 구성 요소에 대한 직접 접근을 제한하는 것을 의미합니다.

예시:

  • 직원이 음수 급여를 가질 수 있을까요?
  • 사람의 나이가 음수가 될 수 있을까요?

이러한 검증은 비즈니스 로직 및 비즈니스 규칙의 일부입니다.

상속

상속은 관련된 객체들을 그룹화하고 공유 로직을 재사용할 수 있게 합니다.

예시: CreditCardPayment 은 공통 결제 동작을 상속받습니다.

Red flag: 대부분의 부모 클래스 메서드를 오버라이드하고 있다면, 상속 구조가 잘못되었을 가능성이 있습니다.

다형성

다형성은 같은 메서드가 구현하는 객체에 따라 다르게 동작하도록 합니다.

예시: processPayment(amount) – Stripe는 한 방식으로, PayPal은 다른 방식으로 처리하지만 메서드 이름은 동일하게 유지됩니다.

추상화

추상화는 다형성과 손잡고 객체의 필요한 기능만 노출함으로써 작동합니다.

OOP에 대한 최종 생각: 올바르게 사용될 때, 이러한 원칙은 버그를 줄이고 유지보수성을 향상시키며 시스템을 확장하기 쉽게 만들고 비즈니스 규칙을 안전하게 보호합니다.

SOLID 원칙

단일 책임 원칙 (SRP)

하나의 단위는 변경될 이유가 하나만 있어야 합니다.

잘못된 설계:

class UserService {
  validateUserData() { /* ... */ }
  saveUserToDatabase() { /* ... */ }
  sendWelcomeEmail() { /* ... */ }
}

올바른 설계:

class UserValidator { /* validates data */ }
class UserRepository { /* handles database */ }
class EmailService { /* sends emails */ }

개방/폐쇄 원칙 (OCP)

소프트웨어 요소는 확장에는 열려 있어야 하고, 수정에는 닫혀 있어야 합니다.

하드코딩된 조건문 대신:

if (paymentType == "stripe") { /* ... */ }

추상화를 사용하세요:

interface PaymentGateway { pay(amount: number): void; }

class StripeGateway implements PaymentGateway { /* ... */ }
class PaypalGateway implements PaymentGateway { /* ... */ }

새 공급자를 추가할 때는 기존 코드를 변경할 필요 없이 새로운 클래스를 만들면 됩니다.

리스코프 치환 원칙 (LSP)

슈퍼클래스의 객체는 서브클래스 객체로 교체해도 프로그램의 정확성이 유지되어야 합니다.

문제 있는 설계:

class Bird { fly() { /* ... */ } }
class Penguin extends Bird { /* cannot fly */ }

개선된 설계:

class Bird { /* common behavior */ }
class FlyingBird extends Bird { fly() { /* ... */ } }
class Penguin extends Bird { /* no fly method */ }

인터페이스 분리 원칙 (ISP)

클라이언트는 사용하지 않는 인터페이스에 의존하도록 강요받아서는 안 됩니다.

잘못된 예:

interface Worker {
  work(): void;
  eat(): void;
}
class RobotWorker implements Worker {
  work() { /* ... */ }
  eat() { /* empty */ }
}

올바른 예:

interface Workable { work(): void; }
interface Eatable { eat(): void; }

class RobotWorker implements Workable { /* ... */ }
class HumanWorker implements Workable, Eatable { /* ... */ }

의존성 역전 원칙 (DIP)

고수준 모듈은 구체적인 구현이 아니라 추상화에 의존해야 합니다.

잘못된 예:

class OrderService {
  private gateway = new StripePaymentGateway();
}

올바른 예:

class OrderService {
  private gateway: PaymentGateway; // injected
}

마무리 생각: 객체지향 프로그래밍은 언어를 제공하고, SOLID는 그 언어의 문법을 제공합니다.

비즈니스 사용 사례: 정적 팩토리 메서드와 SOLID

우리는 if/else 로직 없이 새로운 제공자를 추가할 수 있는 유연한 결제 오케스트레이션이 필요합니다.

1. 계약 정의

interface PaymentGateway {
  pay(amount: number): void;
}

2. 구체적인 게이트웨이 구현

class StripeGateway implements PaymentGateway {
  pay(amount: number): void {
    console.log(`💳 Paid ${amount}$ using Stripe`);
  }
}

class PaypalGateway implements PaymentGateway {
  pay(amount: number): void {
    console.log(`💰 Paid ${amount}$ using PayPal`);
  }
}

class CashOnDeliveryGateway implements PaymentGateway {
  pay(amount: number): void {
    console.log(`📦 Cash on Delivery: ${amount}$ will be collected`);
  }
}

3. 정적 팩토리 생성

class PaymentFactory {
  static create(provider: string): PaymentGateway {
    switch (provider) {
      case "stripe":
        return new StripeGateway();
      case "paypal":
        return new PaypalGateway();
      case "cod":
        return new CashOnDeliveryGateway();
      default:
        throw new Error("Payment provider not supported");
    }
  }
}

4. 팩토리 사용

const gateway = PaymentFactory.create("stripe");
gateway.pay(100);

설계가 SOLID & OOP를 만족하는 방법

  • 캡슐화: 각 게이트웨이는 내부 구현을 숨깁니다.
  • 다형성: 모든 게이트웨이는 pay() 메서드를 공유하지만 동작이 다릅니다.
  • 추상화: 클라이언트 코드는 PaymentGateway 인터페이스에만 의존합니다.
  • SRP(단일 책임 원칙): 각 클래스는 하나의 책임만 가집니다(검증, 데이터 접근, 이메일 전송, 결제 처리 등).

시스템 확장

새로운 제공자(예: Apple Pay)가 필요할 경우:

class ApplePayGateway implements PaymentGateway {
  pay(amount: number): void {
    console.log(`🍏 Paid ${amount}$ using Apple Pay`);
  }
}

팩토리에 추가:

case "applepay":
  return new ApplePayGateway();

기존 클래스들을 수정할 필요가 없습니다.

최종 생각: 이 예제는 정적 팩토리 메서드와 SOLID 원칙, OOP를 결합하면 실제 결제 오케스트레이션 플랫폼에 적합한 깔끔하고 확장 가능한 아키텍처를 만들 수 있음을 보여줍니다.

Back to Blog

관련 글

더 보기 »

핸즈온 실습: Amazon Personalize

!Amazon Personalize https://dev-to-uploads.s3.amazonaws.com/uploads/articles/16ui0v8xk3zc0lybrveg.png 간략한 개요 Amazon Personalize는 기업이 …