-
SOLID 5대 원칙 - SRP카테고리 없음 2023. 11. 14. 08:30
SOLID 5대 원칙이란, 객체 지향 프로그래밍을 할 때 지켜야 할 원칙으로 자주 언급되곤 한다.
오늘은 그 중 Single Responsibility Principle, 단일 책임 원칙에 대해 알아보자.
하나의 모듈은 하나의 책임을 가져야 한다
이런 단언에 가까운 문장을 볼 때, 반례를 떠올려 보는 것이 해당 주장에 힘을 실어준다고 생각하는 편이다.
그래서 위의 문장과 반대되는 예시를 떠올려보자.
새로운 게시글을 저장하는 경우를 예시로, 최대한 간소화해서 표현하면 다음과 같다.
1. 입력된 데이터가 게시글 저장에 필요한 데이터 형식에 맞는지 검사한다.
2. 저장소에 게시글을 저장한다.
만약 위 두 로직을 작성한 코드가 하나의 함수 안에 들어가 있다면, 아래와 같은 모습일 것이다.
class ArticleService { ArticleRepository articleRepository = ArticleRepository.getInstance(); public void saveArticle(String title, String contents) { if(title.length > 30) { // 제목 최대 길이 에러! return; } if(contents.length > 200) { // 콘텐츠 최대 길이 에러! return; } article = new Article(title, contents); articleRepository.save(article); } }보다시피 현재 게시글 제목의 최대 길이 제한은 30자 이하이다.
그런데 만약 게시글 제목의 최대 길이 제한을 50자 이하로 늘리고, 경고 메시지도 바꿔달라는 요청이 들어오면 어떨까?
얼핏 보기에는 title.length > 30 부분의 조건문을 약간 수정하고, 조건문 바디의 에러 메시지도 살짝만 바꾸면 될 것 같다.
그러나 이러한 해결 방법의 문제점은, 수정한 부분이 정상작동하는지 테스트를 시행할 때 드러나게 된다.
게시글 제목의 최대 길이 제한을 변경했으나, 게시글 작성까지 테스트를 해봐야 하는 문제
이 문장에서 무언가 위화감을 느꼈으면 좋겠다.
우리는 위의 게시글 저장 로직에서 게시글 제목 길이 제한과 약간의 에러 메시지 외에는 아무것도 변경하지 않았다.
따라서 게시글을 저장하는 기존의 다른 로직은 아무런 문제없이 실행될 것이라는 걸 99% 확신할 수 있다.
그러나 실제로 해당 변경사항이 잘 동작하는지 확인해보려면,
제목 길이 검사부터 콘텐츠 길이 검사, 저장소에 게시글을 저장하는 것 까지의 모든 과정을 실행해봐야 한다.
왜 이런 문제가 발생했을까?
saveArticle -> 게시글 저장
'게시글 저장' 이라는 우리의 목표를 다시 한번 떠올려보자.
위에서 고려했던 모든 사소한 조건이나 제한 등은 잠시 잊고, 우리가 원하는 것은 '게시글' 을 '저장'하는 것이다.
그래서 메서드 이름도 saveArticle 로 지었지 않았는가?
따라서, saveArticle 은 게시글을 저장하는 단 하나의 책임에만 집중해야 한다.
하나의 모듈을 변경하는 이유는 단 하나여야 한다
위 코드대로라면,
게시글 제목 최대 길이 제한을 변경하는 작업도 게시글 저장 메서드 안에서 코딩 해야하고,
저장소에 게시글을 저장하는 작업에 대해 변경사항이 있을 때에도 게시글 저장 메서드 안에서 코딩해야 한다.
이처럼 하나의 메서드를 변경하는 이유가 점점 많아질수록, 어느 순간에는 두 코드가 섞이게 된다.
이는 문제가 발생했을 때 디버깅을 어렵게 하는 주된 이유가 된다.
개발자마다 '단일 책임' 이라고 느끼는 범위가 다를 수 있다
지금까지의 내용을 정리해보자.
하나의 모듈은 하나의 책임을 가져야 한다는 주장으로 시작해서,
어떤 모듈을 변경하는 이유는 단 하나여야 디버깅과 수정에 용이한 코드가 된다는 것까지 이어졌다.
어찌보면 매우 심플한 원칙인 것 같으나, 실무에 적용할 때에는 분명히 어려움이 있다.
위의 게시글 저장 코드를 보고 누군가는
'게시글을 저장할 때 입력값 검사는 무조건 해야 하니까, saveArticle의 책임이라고 볼 수도 있지 않나?' 라고 생각할 수 있다.
이처럼 간단한 예시에도 개발자마다 이견이 있을 수 있는데, 더욱 크고 복잡한 실무 프로젝트에서는 이러한 의견 충돌이 더욱 빈번할 것이다.
의견 충돌이 일어나게 되는 이유를 한 번 알아보자.
반대의 케이스 : 낮은 응집도
하나의 모듈은 하나의 변경 사유만 가져야 하므로, 모든 모듈을 최대한 잘게 나누면 원칙도 지키고 동료와 논쟁할 필요도 없지 않을까?
그러나 이는 관심사가 같음에도 불구하고 서로 모여있지 않아서, 코드를 수정할 때 어느 곳을 고쳐야 하는지 알 수 없게 만든다.
위에서 봤던 게시글 저장에서 처리해야 하는 부가 기능은 입력값 검사 하나 뿐이라서 이를 분리했을 때 찾기 어렵지 않겠지만,
부가 기능이 10개쯤 되고, 이들이 모두 완벽하게 분리되어 있다면, 수정이 필요할 때 어느 곳부터 찾아봐야 할 지 난감할 것이다.
따라서 SRP 에 입각해 모듈을 설계하되, 응집도가 너무 떨어지지 않게 균형을 유지하는 것이 가장 어렵고도 중요한 것이다.