SOLID Principles: 실제 세계에서 살아남는 코드를 작성하기

발행: (2026년 2월 27일 오후 04:49 GMT+9)
7 분 소요
원문: Dev.to

Source: Dev.to

위 링크에 있는 글의 전체 내용을 제공해 주시면, 해당 텍스트를 한국어로 번역해 드리겠습니다.
(코드 블록, URL 및 마크다운 형식은 그대로 유지됩니다.)

Introduction

소프트웨어를 작성하는 것은 단순히 동작하게 만드는 것이 아닙니다.
오늘, 내일, 그리고 1년 후에도 동작하도록 만드는 것이 중요합니다.

지난 주에는 이벤트‑드리븐 아키텍처—시스템이 어떻게 소통하고 확장되는지—에 대해 살펴보았습니다.
이번 주에는 더욱 근본적인 주제로 들어갑니다: SOLID 원칙.

SOLID는 프레임워크나 라이브러리가 아니라 사고 방식입니다. 각 글자는 깨끗하고 유연하며 유지보수가 쉬운 소프트웨어를 설계하는 데 도움이 되는 원칙을 나타냅니다.

Single Responsibility Principle (SRP)

하나의 일 = 하나의 작업
클래스는 오직 하나의 책임만 가져야 하며, 변경 이유도 하나만 있어야 합니다.

클래스가 사용자 등록, 이메일 전송, 데이터베이스 저장을 모두 처리한다면 책임이 너무 많아집니다. 숟가락이 이를 닦아서는 안 되듯이, 클래스도 모든 일을 하려고 하면 안 됩니다.

현실 세계 비유

  • 요리사는 요리한다.
  • 운전자는 운전한다.
  • 교사는 가르친다.

Diagram

classDiagram
    class UserService {
        +registerUser()
    }
    class EmailService {
        +sendEmail()
    }
    class UserRepository {
        +save()
    }
    UserService --> EmailService
    UserService --> UserRepository

Figure 1: Single Responsibility Principle – 각 클래스는 하나의 책임만 가집니다.

Open/Closed Principle (OCP)

기존 장난감을 깨뜨리지 않고 새로운 장난감을 장난감 상자에 추가할 수 있습니다.
기존 코드를 수정하지 않고 동작을 확장합니다.

새로운 것이 필요할 때마다 기존 코드를 변경하는 대신, 코드를 확장합니다. 좋은 소프트웨어 설계는 파괴 없이 성장할 수 있게 합니다.

Real‑world analogy

새로운 장치를 추가하기 위해 집의 벽을 부수지 않고, 기존 콘센트에 플러그를 꽂습니다.

Diagram

classDiagram
    class Payment {
        <> 
        +pay(amount)
    }
    class CreditCardPayment {
        +pay(amount)
    }
    class PayPalPayment {
        +pay(amount)
    }
    class PaymentProcessor {
        +process(payment)
    }
    Payment  Payment

Figure 2: Open–Closed Principle – 기존 코드를 수정하지 않고 기능을 확장합니다.

리스코프 치환 원칙 (LSP)

초콜릿 우유를 딸기 우유로 바꾸어도 여전히 우유처럼 동작해야 합니다.
무언가가 다른 무언가의 “유형”이라면, 그 유형에 맞게 올바르게 동작해야 합니다.

예시

“펭귄은 새이다” 하지만 “모든 새는 날 수 있다”는 펭귄에게는 거짓입니다. 문제는 설계 가정에 있으며, 펭귄이 아닙니다.

규칙: 서브클래스가 기대를 깨뜨리도록 강요하지 마세요. 서브클래스가 부모와 완전히 동일하게 동작할 수 없다면, 상속 설계가 잘못된 것입니다.

다이어그램

classDiagram
    class Bird
    class FlyingBird {
        <> 
        +fly()
    }
    class Sparrow
    class Penguin

Interface Segregation Principle (ISP)

필요하지 않은 일을 강요하지 마세요.

Example

아이에게 “요리”와 “운전” 같은 책임을 주면 과도합니다. 실제로 필요한 것만 주세요.

Analogy

TV 리모컨에는 TV 버튼만 있고, 에어컨 리모컨에는 에어컨 버튼만 있습니다. 큰 인터페이스는 거대한 리모컨과 같고, 작고 구체적인 인터페이스는 깔끔하고 집중된 형태입니다.

Diagram

classDiagram
    class Workable {
        <> 
        +work()
    }
    class Eatable {
        <> 
        +eat()
    }
    class Human
    class Robot
    Workable  
        +save()
    }
    class MySQLDatabase
    class MongoDatabase
    class OrderService {
        +processOrder()
    }
    Database  Database

그림 5: 의존성 역전 원칙 – 구체적인 구현이 아니라 추상에 의존하라.

Dependency Inversion Principle (DIP)

고수준 모듈은 저수준 모듈에 의존해서는 안 되며, 두 모듈 모두 추상화에 의존해야 합니다. 이는 결합도를 낮추고 시스템을 보다 유연하게 만듭니다.

(위 다이어그램은 이 원칙을 보여줍니다.)

마무리 생각

SOLID 원칙은 단순한 이론이 아니라, 여러분이 다음과 같은 코드를 작성하도록 도와줍니다:

  • 이해하기 쉽다
  • 확장하기 쉽다
  • 유지보수가 쉽다
  • 쉽게 깨지지 않는다

좋은 설계는 오늘의 고통을 내일의 고통으로부터 구해줍니다. SOLID를 따를 때, 소프트웨어는 깔끔하게 성장합니다 — 마치 잘 정돈된 장난감 상자처럼.

당신은 어떠세요?
여러분은 설계가 부실해서 나중에 문제가 된 프로젝트에 참여한 적이 있나요? 가장 어려움을 겪는 SOLID 원칙은 무엇인가요? 댓글로 이야기해 주세요.

0 조회
Back to Blog

관련 글

더 보기 »

과거와의 마지막 춤🕺

소개 안녕하세요 dev.to 커뮤니티! 일주일 전에 저는 저를 소개하고, 웹 개발을 떠나 cryptograph에 집중하기 위해...