목차
- 서론: 기능 구현 그 너머, 기술 부채와의 싸움
- SRP (단일 책임 원칙): 클래스의 역할을 한 문장으로 정의하기
- OCP (개방-폐쇄 원칙): if-else 지옥에서 탈출하는 법
- LSP와 ISP: 거대한 인터페이스를 쪼개면 생기는 변화
- DIP (의존 역전 원칙): 테스트가 즐거워지는 마법
- 마치며: 완벽함보다는 '방향성'이 중요한 이유
- Q&A: SOLID 원칙, 이것이 궁금해요!

1. 서론: 기능 구현 그 너머, 기술 부채와의 싸움
개발을 처음 시작했을 때는 그저 기능이 돌아가기만 하면 된다고 생각했어요. 그런데 코드가 쌓이고 서비스가 커지다 보니, 어제 짠 코드를 오늘 수정하는 게 두려워지는 순간이 오더라고요.
이른바 기술 부채가 쌓인다는 것을 몸소 체험하게 된 거죠. 그때 가장 먼저 찾아보게 된 것이 바로 객체지향 설계의 기본인 SOLID 원칙이었어요.
오늘은 제가 실무 코드를 작성하면서 SOLID 원칙을 어떻게 이해하고 적용하려 노력했는지, 그 경험을 나눠보려고 합니다.
2. SRP (단일 책임 원칙): 클래스의 역할을 한 문장으로 정의하기
단일 책임 원칙, 즉 SRP는 하나의 클래스는 하나의 기능만 가져야 한다는 원칙이에요. 처음에는 이게 참 당연한 소리처럼 들렸어요.
하지만 막상 코드를 짜다 보면, 이 클래스 저 클래스에서 호출하는 기능을 한곳에 몰아넣는 편이 개발 속도는 훨씬 빠르거든요. 저도 예전에는 결제 처리와 로그 저장, 이메일 발송까지 한 클래스에 다 넣은 적이 있었어요.
결국 유지보수 과정에서 큰 코다치게 되었죠. 특정 로직을 수정하면 연관 없는 기능까지 에러가 나는 상황이 반복되더라고요. 요즘은 무조건 클래스의 역할이 무엇인지 한 문장으로 정의해보려고 노력해요.
클래스 이름 옆에 어떤 일을 하는지 주석을 달았을 때, 그리고라는 접속사가 들어간다면 그건 이미 책임이 나뉘어야 한다는 신호더라고요.
3. OCP (개방-폐쇄 원칙): if-else 지옥에서 탈출하는 법
확장에는 열려 있고 수정에는 닫혀 있어야 한다는 OCP 원칙은 제가 가장 좋아하는 원칙이에요. 실무에서 새로운 기능을 추가할 때 기존 코드를 건드리는 건 정말 위험한 일이거든요.
저는 이 원칙을 지키기 위해 인터페이스를 적극적으로 활용하기 시작했어요. 예를 들어, 다양한 결제 수단을 처리하는 로직을 짤 때 처음에는 if-else 문을 떡칠했었어요.
그런데 이제는 결제 방식을 인터페이스로 정의하고, 각 결제 수단별로 클래스를 따로 구현해요. 이렇게 하면 새로운 결제 수단이 추가되어도 기존 결제 로직을 건드릴 필요가 없죠. 제가 짠 코드지만 나중에 수정할 때 정말 마음이 편해지더라고요.
4. LSP와 ISP: 거대한 인터페이스를 쪼개면 생기는 변화
리스코프 치환 원칙과 인터페이스 분리 원칙은 사실 인터페이스를 얼마나 잘 설계하느냐의 문제와 맞닿아 있어요. 예전에는 모든 기능을 다 담은 거대한 인터페이스를 하나 만들어두고, 필요할 때마다 가져다 썼거든요.
그런데 이 방식은 사용하지 않는 메서드까지 억지로 구현해야 하는 불필요함을 만들더라고요. 그래서 요즘은 필요한 기능만 골라서 인터페이스를 정의하려고 해요.
ISP를 적용해서 인터페이스를 잘게 쪼개다 보니, 코드가 더 명확해지고 객체 간의 결합도도 확실히 낮아지더군요. 작은 차이지만 이런 디테일이 나중에 엄청난 생산성 차이를 만들어내는 것 같아요.
5. DIP (의존 역전 원칙): 테스트가 즐거워지는 마법
마지막으로 의존 역전 원칙, DIP는 추상화에 의존하라는 원칙이죠. 쉽게 말해 구체적인 클래스가 아니라 인터페이스나 추상 클래스를 바라보게 하라는 거예요.
처음에는 의존성 주입(DI) 개념이 참 낯설었는데, 막상 적용해보니 테스트 코드를 작성할 때 신세계가 열리더라고요. 실제 DB나 외부 API 없이도 Mock 객체를 만들어 기능을 검증할 수 있게 되니까요.
6. 마치며: 완벽함보다는 '방향성'이 중요한 이유
물론 모든 코드에 SOLID 원칙을 완벽하게 적용하는 것은 현실적으로 어려워요. 때로는 빠른 배포를 위해 타협해야 하는 순간도 분명히 있죠. 하지만 중요한 건 이런 원칙들을 기준으로 삼고 코드를 바라보는 시각을 가지는 것이라고 생각해요.
저도 아직 갈 길이 먼 주니어 개발자이지만, SOLID 원칙을 고민하며 짠 코드들이 확실히 버그도 적고 나중에 다시 볼 때도 훨씬 읽기 편하더라고요. 비슷한 고민을 하고 계신 분들이 있다면, 거창한 리팩토링보다는 오늘 작성하는 클래스 하나에 이 원칙들을 살짝만 녹여보는 건 어떨까요? 사소한 습관이 모여서 정말 좋은 개발자가 되는 길이라고 믿습니다.
댓글 쓰기