SOLID 원칙

SOLID Principles

개념

객체 지향으로 코드를 나눌 때 나중에 고치기 쉬운 구조가 되도록 지키는 다섯 가지 설계 지침입니다.

등장 배경

코드를 어떤 덩어리로 자를지는 처음에는 문제가 되지 않습니다. 파일이 스무 개일 때는 어디에 무엇이 있는지 다 기억하고, 한 곳을 고쳐도 영향이 어디까지 가는지 눈으로 따라갑니다.

반년이 지나면 달라집니다. 할인 규칙 하나를 추가하려고 결제를 다루는 파일을 열었는데 800줄이고, 그 안에 금액 계산과 영수증 메일 발송과 기록 남기기와 환율 변환이 함께 들어 있습니다. 할인 조건을 넣으려면 그 800줄을 읽어야 하고, 고치고 나면 영수증 메일이 안 나갑니다.

더 나쁜 것은 이 상태가 서서히 온다는 점입니다. 기능을 하나씩 더할 때마다 가장 가까운 파일에 붙였을 뿐인데, 그렇게 붙인 것이 쉰 번 쌓이면 아무도 열고 싶지 않은 파일이 됩니다. 코드 스멜이라 부르는 신호가 여기서 나옵니다.

2000년대 초에 이런 경험을 다섯 가지 지침으로 정리한 묶음이 나왔습니다. 지침마다 이름이 있고 그 앞 글자를 모으면 SOLID가 됩니다. 새로운 기술이 아니라 겪고 나서 적어 둔 규칙에 가깝습니다.

작동 방식

다섯 지침은 각각 코드를 놓고 던지는 질문 하나씩입니다. 답이 나쁘면 자르는 자리를 옮깁니다.

  1. 단일 책임 원칙입니다. 이 덩어리가 바뀌어야 하는 이유가 몇 개인지 묻습니다. 금액 계산은 정책이 바뀌면 고쳐야 하고 영수증 메일은 문구가 바뀌면 고쳐야 하니, 바뀌는 이유가 둘이면 덩어리도 둘이어야 합니다. 이 질문에 답한 결과를 재는 눈금이 응집도입니다.
  2. 개방-폐쇄 원칙입니다. 새 경우를 더할 때 기존 코드를 고쳐야 하는지 묻습니다. 할인 종류가 늘 때마다 계산 함수 안의 조건문을 하나씩 늘리고 있다면 답은 그렇다입니다. 할인 하나를 새 파일로 추가하면 끝나도록 바꿔 두면, 기존 파일은 손대지 않고 새것만 더하게 됩니다.
  3. 리스코프 치환 원칙입니다. 자식을 부모 자리에 끼워 넣어도 프로그램이 그대로 도는지 묻습니다. 직사각형을 상속한 정사각형을 만들면, 가로만 300으로 바꾸는 코드가 정사각형에서는 세로까지 바뀌어 결과가 어긋납니다.
  4. 인터페이스 분리 원칙입니다. 쓰는 쪽이 쓰지도 않는 기능까지 떠안는지 묻습니다. 기능 스무 개가 달린 창구 하나를 두면, 그중 둘만 쓰는 쪽도 스무 개가 바뀔 때마다 영향을 받습니다.
  5. 의존성 역전 원칙입니다. 위쪽 규칙이 아래쪽 구현을 직접 아는지 묻습니다. 할인 계산 코드가 특정 데이터베이스를 직접 부르고 있으면 저장소를 바꿀 때 계산 규칙도 함께 손봐야 합니다. 사이에 창구를 하나 두고 양쪽이 그 창구만 알게 하면 한쪽을 갈아 끼워도 다른 쪽이 그대로입니다. 이 거리를 재는 눈금이 결합도입니다.

다섯을 관통하는 것은 하나입니다. 바뀔 곳과 바뀌지 않을 곳을 미리 갈라 두는 일입니다. 다섯 질문은 그 경계가 지금 어디에 그어져 있는지 확인하는 서로 다른 각도입니다.

쓰이는 곳

가장 자주 쓰이는 자리는 코드 리뷰입니다. 이 클래스가 마음에 안 든다는 말과 이 클래스가 바뀌어야 하는 이유가 둘인 것 같다는 말은 다르게 받아들여집니다. 뒤엣말은 취향이 아니라 확인할 수 있는 지적이라 대화가 다음 단계로 넘어갑니다.

리팩터링을 할 때도 기준으로 씁니다. 동작을 그대로 두고 구조만 고치는 작업인데, 무엇을 어느 방향으로 옮길지 정해 주는 것이 없으면 취향대로 움직이게 됩니다. 코드 스멜이 보일 때 다섯 질문을 차례로 던지면 대개 하나가 걸리고, 그 질문이 옮길 방향을 알려 줍니다.

설계를 논의하는 자리에서는 디자인 패턴과 짝을 이룹니다. 패턴은 자주 나오는 문제에 대한 해법 목록이고, 이 원칙은 그 해법을 골라야 할지 판단하는 기준입니다. 더 큰 단위로 경계를 나눌 때는 도메인 주도 설계처럼 업무 언어를 기준으로 삼는 방법이 이 자리를 대신합니다.

쓰지 않는 자리도 분명합니다. 한 번 쓰고 버릴 스크립트나 아직 요구사항이 정해지지 않은 초기 코드에는 적용하지 않습니다. 원칙을 지키는 데는 파일 수와 간접 단계가 늘어나는 비용이 따르고, 바뀔 일이 없는 코드에서는 그 비용만 남습니다.

실무 용례

"이 클래스가 바뀌어야 하는 이유가 둘인 것 같아요. 메일 보내는 부분을 빼죠."

단일 책임 질문을 리뷰 의견으로 옮긴 말입니다.

"할인이 추가될 때마다 여기 조건문이 늘어요. 할인을 따로 두는 구조로 바꿉시다."

새 경우를 더할 때 기존 코드를 고치고 있다는 지적입니다.

"이건 스크립트라 원칙까지 갈 필요 없어요. 한 번 돌리고 지울 코드입니다."

비용을 치를 자리가 아니라는 판단입니다.

페이지덱에서는 태오가 결제 쪽을 정리할 때 이 질문들을 순서대로 던졌습니다. 800줄짜리 파일에서 영수증 메일과 기록 남기기를 먼저 떼어 냈고, 할인 규칙은 종류마다 파일을 나눠 새 할인을 더할 때 기존 파일을 열지 않게 만들었습니다.

문서 저장 쪽은 손대지 않았습니다. 3년 동안 구조가 바뀐 적이 없고 앞으로도 바뀔 예정이 없어서, 나누는 값이 나누지 않는 값보다 크지 않다고 봤습니다.

흔한 오해

다섯을 언제나 전부 지켜야 한다고 보는 경우가 가장 많습니다. 원칙이라는 이름이 붙어 있고 다섯이 한 묶음으로 소개되니 그렇게 읽힙니다. 하지만 각각에는 값이 붙습니다. 창구를 하나 두면 코드를 따라 읽을 때 한 단계를 더 건너뛰어야 하고, 파일을 셋으로 나누면 열어야 할 파일이 셋이 됩니다. 바뀔 일이 없는 코드에 이 값을 치르면 남는 것은 복잡함뿐입니다. 100줄짜리 기능에 인터페이스 다섯 개와 파일 열두 개가 붙은 코드는 원칙을 지킨 것이 아니라 기술 부채를 다른 모양으로 만든 것입니다.

객체 지향에서만 쓰는 이야기라고 보는 것도 흔합니다. 클래스와 상속이라는 말로 설명되니 자연스러운 오해입니다. 다만 다섯 질문은 클래스가 아니라 경계에 대한 것입니다. 이 덩어리가 바뀌는 이유가 몇 개인지, 새 경우를 더할 때 기존 것을 고쳐야 하는지는 함수를 나눌 때도 서비스를 나눌 때도 같은 질문입니다. 클래스를 쓰지 않는 언어에서 일하더라도 다섯 질문은 그대로 쓸 수 있습니다.

같이 보면 좋은 페이지

  • 소프트웨어 아키텍처

    네 갈래 가운데 설계 지식이 어디에 놓이고 무엇을 보완하는지 봅니다

  • 디자인 패턴

    판단 기준과 해법 목록의 관계여서 둘을 이어 읽으면 쓰는 순서가 잡힙니다

마지막 업데이트 2026-09-16