
SOLID는 객체지향 프로그래밍에서 유지보수성과 확장성을 높이기 위한 5가지 설계 원칙으로 단일 책임 원칙, 개방-폐쇄 원칙, 리스코프 치환 원칙, 인터페이스 분리 원칙, 의존성 역전 원칙이 있습니다.
실제로, 뉴쓱이라는 프로젝트에서 레디스 기반의 카운팅 시스템을 구축하며 이를 적용한 사례를 통해 알아보겠습니다.
단일 책임 원칙은 하나의 클래스가 하나의 책임만 가지도록 설계하는 것을 말합니다.
레디스 기반의 카운팅 시스템에는 두 가지 책임이 있습니다. 하나는 레디스 카운팅 수행, 하나는 수행된 카운팅을 실제 DB에 동기화 하는 것입니다. 이를 다음과 같이 클래스를 분리했습니다.

개방-폐쇄 원칙은 확장에는 열려 있고 변경에는 닫혀 있도록 설계하는 것을 말합니다.
다음과 같이 RedisCounterService가 직접 RedisHashService를 직접 구현하지 않고, RedisCounterService 인터페이스를 생성해 RedisHashService를 확장했습니다. 이를 통해, RedisCounterServiceImpl를 수정하지 않고 새로운 구현체를 추가해 구현할 수 있습니다.

리스코프 치환 원칙은 부모 클래스의 기능을 자식 클래스가 대체할 수 있도록 설계하는 것을 말합니다.
다음과 같이 RedisCounterServiceImpl가 RedisCounterService를 구현하므로 RedisCounterService에 대한 의존 관계를 가진 ArticleService에서 RedisCounterServiceImpl 변경이 발생해도 문제 없이 수행할 수 있습니다.

인터페이스 분리 원칙은 클라이언트가 사용하지 않는 기능에 의존하지 않도록 인터페이스를 분리하는 것을 말합니다.
다음과 같이 RedisCounterService를 분리할 수 있지만, 현재는 Hash를 다른 용도로 사용할 예정이 없으므로 복잡도가 증가한다고 생각하여 이는 수행하지 않겠습니다.

의존성 역전 원칙은 구현체에 의존하지 않고, 추상화에 의존하도록 설계하는 것을 말합니다.
다음과 같이 RedisCounterService에 대한 의존 관계를 가지므로 RedisCounterServiceImpl을 변경하거나 다른 구현체로 교체해도 ArticleService와 CounterSchedulingServiceImpl 를 수정할 필요 없습니다.
