Skip to main content

Command Palette

Search for a command to run...

올바른 객체지향 설계 - 'solid 원칙' 이란?

Updated
2 min read

객체지향 프로그래밍은 현대 프로그램 언어의 다수가 채택하고 있는 프로그래밍 개발 방법입니다. 로버트 마틴이란 분이 객체지향 프로그래밍 설계를 일관되게 할 수 있도록 2000년대 초반 5가지 원칙을 두문자어로 해서 SOLID라고 소개하였습니다. SOLID의 의미는 각각 다음과 같습니다.

image.png

SOLID 원칙은 객체지향적 코드 일관성을 유지할 수 있게 하며 코드의 모듈화를 점진적으로 가능하게 합니다. 처음부터 원칙대로 코드를 전개하기는 어려울 수 있으므로 리펙토링을 통해 점진적으로 코드를 개선하면서 SOLID 원칙에 부합하도록 가다듬게 됩니다.

다음으로 SOLID 원칙에 대해 각각 살펴보도록 합시다.

S - 단일 책임 원칙 (Single Responsibility Principle, SRP)

"하나의 클래스 또는 모듈 또는 함수는 하나의 책임만 가진다."는 원칙으로 다섯가지 원칙 중 가장 일반적이고 대표적인 원칙이 될 것 같습니다. 여기서 살펴봐야 할 단어는 "책임"입니다. 목적을 달성하기 위한 역할 정도로 이해하면 될 것 같습니다. 역할에 대한 구현은 은닉 되어야 하며 제공하는 서비스는 이 역할에 맞게 최대한 좁게 - 목적에 맞게 함수의 기능이 작으면서 적고, 명확하게 - 조정되어야 합니다.

O - 개방-폐쇄 원칙 (Open/Close Principle, OCP)

"모듈, 클래스 등 소프트웨어 요소의 확장은 열려 있으나 변경은 닫혀있게" 하는 원칙입니다. 여기서 살펴봐야 할 단어는 "확장"과 "변경"인데요, "확장"은 소스 수정 없이 확장 가능한 구조를 의미하고 "변경"은 소스코드를 수정하는 것을 의미합니다. 구조를 추상적으로 잘 디자인하게 되면 더이상 구조 모듈은 변경할 필요 없이 (Close) 기능을 확장 할 수 (Open) 있게 됩니다.

L - 리스코프 치환 원칙 (Liskov substitution Principle, LSP)

"베이스 클래스를 이용하여 구현된 기능은 파생 클래스의 인스턴스로도 목적에 맞는 동작을 수행해야 한다."는 원칙 입니다. 여기서 베이스 클래스는 부분 구현된 추상 클래스일 수도 있고, 완전히 동작하는 구현 클래스일 수도 있습니다. 리스코프 치환 원칙을 준수한다는 것은 클래스를 디자인한 추상단계에서 정확히 올바른 기능을 구현했다는 것을 의미합니다.

I - 인터페이스 분리 원칙 (Interface Segregation Principle, ISP)

"구현하지 않아도 되는 다양한 기능명세 보다는 목적에 맞는 여러개의 인터페이스로 기능명세를 구현하는" 원칙 입니다. 이 원칙을 준수하게 되면 인터페이스가 원자성을 가지게 됩니다. 즉, 해당 인터페이스를 준수한다면, 어떠한 구현체라도 동작하는 기능을 구현할 수 있게 됩니다. 이것은 코드를 점진적으로 모듈화 하는데 좋은 원칙이 됩니다.

D - 의존관계 역전 원칙 (Dependency Inversion Principle, DIP)

"하위 모듈과 상위 모듈의 의존성을 직접 형성하지 않고 추상화(예를 들어 인터페이스)를 통해 종속성을 제거하는" 원칙입니다. 다음의 위키백과-종속성 반전 원리의 도식을 살펴보시죠.

전통적인 레이어 패턴의 구조는 다음과 같은 종속 관계를 형성하게 됩니다.

image.png

종속성 반전 패턴을 적용하면 다음과 같은 종속 관계를 형성하게 됩니다.

image.png

Policy LayerMachanism Layer 그리고 Utility Layer는 인터페이스를 통해 상호 관련을 맺게 되어 직접적인 종속성이 없어지게 됩니다.

SOLID 원칙을 반드시 지켜야 하나요?

모든 원칙이 그러하듯이 반드시 지켜야 할 필요는 없습니다. 하지만 팀으로 개발을 진행할 경우 코딩 스타일 가이드를 준수해야 코드 가독성이 올라가는 것 처럼 SOLID 원칙은 팀의 코드 일관성을 높이는 원칙이 될 수 있습니다. SOLID 원칙을 몰라도 객체지향 프로그래밍은 할 수 있지만, 동일한 원칙을 채택해야 협업의 퀄리티는 올라가겠죠. 그리고 꼭 팀 개발이 아니더라도 본인의 객체지향 프로그래밍의 일관성과 실력을 늘리는데 SOLID 원칙을 적용할 수 있습니다. 리팩토링을 통해 SOLID 원칙을 점진적으로 적용해 봅시다.

More from this blog

개발, 테스트, 운영에서의 도커 활용

핵심 원칙: "한 번 빌드하고, 어디서든 실행한다 (Build once, run anywhere)" 도커의 가장 큰 장점은 환경 일관성입니다. 동일한 도커 이미지를 사용하여 개발, 테스트, 운영 환경을 구성함으로써 "제 PC에서는 됐는데..." 하는 문제를 최소화할 수 있습니다. 1. 개발 단계 (Development) 목표: 빠른 코드 변경 반영, 쉬운 디버깅, 실제 운영 환경과 유사한 환경 구성. Docker 사용 방안: Dockerf...

May 9, 20256 min read17

[EF Core] 데이터 삭제 시 소프트 삭제 적용

DB에서 데이터를 삭제하면 일반적으로 복구할 수 없습니다. 또한 관계에 따라 영구 삭제 자체가 어려울 수도 있습니다. 그래서 데이터를 영구 삭제하는 대신 IsDeleted 속성을 true로 주고 IsDeleted 속성을 필터링해서 조회하는 방법을 사용하기도 합니다. 이를 소프트 삭제라고 합니다. 그런데 EF에서 알아서 데이터 삭제 시 소프트 삭제를 하고 쿼리시 IsDeleted 속성을 체크해서 삭제한 데이터를 제외한 데이터만 쿼리하게 하는 ...

Mar 18, 20243 min read20

[EF Core] ValueConverter를 이용해서 엔터티 속성의 도메인 관리

EF Core를 사용하면서 문자열 길이 등의 특성을 일일이 지정하는 것은 번거롭습니다. ... [MaxLength(32)] public string? 제목 { get; set; } 엔터티가 한 개일 때는 상관이 없으나 제목 유형이 여러 엔터티에 사용될 경우 유형을 지정하기 번거롭습니다. 속성 유형을 도메인으로 관리하면 참 편할텐데요, ValueConverter를 이용할 수 있습니다. 그런데 이것을 인터페이스 정적 추상를 사용해서 다음처럼 ...

Mar 16, 20242 min read8

디모이 블로그

154 posts

.NET 관련 기술을 선호하고 새로운 언어를 배우는데 관심이 있습니다.