SRP(Single Responsibility Principle)이란?
클래스는 하나의 책임만 가져야 한다.
SRP(Single Responsibility Principle)은 하나의 객체가 하나의 책임만을 가져야한다는 원칙이다. 아주 간단하고 명료한 명제이지만 소프트웨어 개발에 있어서 "책임"이라는 단어의 범주는 한 마디로 표현하기가 어렵다. 그래도 굳이 한 마디로 표현하자면 논리적으로 설계된 하나의 기능이라고 볼 수 있다. 다만 여기서 말하는 기능의 기준은 클래스가 정의한 메서드나 상속 구조, 사용자의 수를 말하는 것은 아니다.
예를 들어보자. 누군가 당신에게 뉴스 웹 페이지에서 기사 내용을 가져와 프로그램에 나타내는 소프트웨어 개발을 요청했다고 하자. 당신은 웹페이지 주소에서 뉴스 내용을 가져오는 Crawler라는 객체를 정의할 것이다. 이때 Crawler의 책임은 웹페이지 주소에서 뉴스 내용을 가져오는 것일 뿐이다. 그 외에도 목표한 프로그램을 구현하기 위해서는 뉴스 웹페이지 주소가 유효한지 확인하는 작업이나 프로그램에 기사 내용을 출력해주는 작업도 있을테지만, Crawler의 책임은 웹 페이지 내용을 가져오는 것 뿐이다. 그 외의 작업은 별도의 클래스를 정의해야 할 것이다.
예시
public class Crawler
{
public string GetURL()
{
return "";
}
public void Display()
{
// Display
}
public void Crawl()
{
var url = GetURL();
// Crawling
Display();
}
}
만약에 Crawler라는 객체가 Crawling할 웹 페이지의 url을 수집하는 기능, Crawling 기능, Crawling한 내용을 화면에 나타내는 기능을 구현했다고 가정해보자. 지금 당장을 원하는 기능이 구현되었다고 생각할 지 모른다. 하지만 이미 해당 기능이 배포된 후에 대상 웹 페이지의 url 수집 방법이 변경되었다고 생각해보자. 또는 프로그램 화면에 나타내는 방식이 변경되었다고 생각해보자. Crawler의 한 가지 책임은 주어진 url의 웹 페이지 내용을 가져오는 것인데, 책임밖의 이유로 Crawler의 코드가 변경되어야 할 것이다.
그렇다면 위 코드는 어떻게 해야 SRP 원칙을 만족할 수 있을까?
public class Crawler
{
public IEnumerable<string> Crawl(string url)
{
yield return "content";
}
}
public class URLGetter
{
public string Get() { return ""; }
}
public class Displayer
{
public void Display(IEnumerable<string> crawled)
{
}
}
위와 같이 각각의 책임에 따라 알맞는 객체를 정의한다. 그리고 이들을 아래와 같이 사용한다.
var urlGetter = new URLGetter();
var displayer = new Displayer();
var crawler = new Crawler();
var url = urlGetter.Get();
var crawled = crawler.Crawl(url);
displayer.Display(crawled);
위와 같이 변경함으로써 책임이 아래와 같이 분산된다.
- URLGetter : 뉴스 웹페이지 URL 수집
- Crawler : 입력받은 URL 페이지 Crawling
- Displayer : 입력받은 문자열 출력
만약 웹페이지 주소가 유효하지 않거나 수집 방법이 변경된다면 URLGetter가 책임을 지게 될 것이고, 화면 출력 방식이 변경된다면 Displayer가 책일을 지게 될 것이다. Crawler는 오로지 Crawling과 관련된 책임만 지게 될 것이다.
소감
가장 중요한 것은 기본이라는 말이 있다. SRP는 객체지향 소프트웨어를 개발하는 개발자로써는 아주 기본적인 원칙일 것이다. 하지만 업무를 바쁘게 하거나 많은 사람들과 프로젝트를 함께 진행하다보면 이 기본적인 원칙이 지켜지지 않을 경우가 많다. 책임을 구분지어 별도의 클래스를 정의하는 것보단 책임이고 뭐고 코드 몇줄로 이슈를 해결할 수 있기 때문이다. 하지만 그렇게 개발을 하고 프로젝트를 완성한다고 하더라도 그것이 과연 완성일까? 고객의 요구사항은 언제나 변하고 변하는 요구사항에도 우리는 튼튼한 소프트웨어를 만들어야 한다. 그럴수록 기본이 더 중요한 것이 아닐까?
'Software Develop > 개발이론' 카테고리의 다른 글
SOLID원칙 - ISP(Interface Segregation Principle) (0) | 2023.01.16 |
---|---|
SOLID원칙 - LSP (Liskov Substitution Principle) (0) | 2023.01.16 |
SOLID원칙 - OCP (Open Closed Principle) (0) | 2023.01.16 |
의존성 주입 (Dependency Injection) (2) | 2023.01.13 |