Seongwon Lim

[OOP] 객체지향 설계 원칙 SOLID - SRP(단일 책임 원칙) 이란? 본문

OOAD

[OOP] 객체지향 설계 원칙 SOLID - SRP(단일 책임 원칙) 이란?

limsw 2022. 9. 2. 14:59
반응형

서론

객체 지향 프로그래밍을 할 때 좋은 설계를 하는 것은 매우 중요하다. 따라서 사람들은 다양한 디자인 패턴들을 적용하여 개발을 진행한다.

이렇게 다양한 디자인 패턴에 기반하여 설계를 해야 추후에 시스템 유지보수 측면 혹은 시스템을 확장할 때 용이하게 개발을 진행할 수 있다.

 

이번 글에서는 객체 지향 설계에서 사용되는 다양한 원칙(디자인  패턴) 중에서, 2000년대 초반 로버트 마틴에 의해 정의된 객체지향 설계의 5가지 기본 원칙을 마이클 페더스가 5가지 원칙의 앞글자만 따서 정의한 SOLID 원칙 중에서 S에 해당하는 단일 책임 원칙(SRP)의 개념에 대해서 알아보고자 한다.

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

단일 책임 원칙은 모든 클래스는 단 하나의 책임만을 가져야 한다는 의미이다.

객체지향 관점에서 책임(Responsibility)이란, 특정 객체가 어플리케이션 기능을 구현하기 위한 상호작용에 참여하기 위해 작성된 로직을 일컫는다. 다시 말하면, 단일 책임을 가져야 한다는 뜻은 하나의 클래스(혹은 함수)는 단 하나의 액터를 가져야 한다고 이해할 수 있다.

 

  • 액터(Actor) : 클래스를 변화(변경)시킬 수 있는 주체 혹은 서비스를 이용하는 주체

한 클래스에 여러 개의 기능(책임)이 들어있다면 어떠한 단점이 존재할까?

여러 기능들이 서로서로 어느 정도의 의존성을 가지고 있다면, 특정 기능을 수정할 때 다른 기능들 또한 영향을 받게 된다.

결과적으로는 한 기능을 수정하면 다른 기능들 또한 수정을 해야 하는 경우가 발생하고 이는 시스템 유지보수 비용만 증가하는 결과를 초래한다.

 

즉, 한 클래스에 여러 개의 책임이 존재하면 원치 않는 의존성 때문에 결합도가 증가할 수 있다.

 

결합도(Coupling)와 응집도(Cohesion)에 대한 개념이 필요한 분들은 아래 글을 참고하면 좋을 것 같다.

 

 

[OOAD] 결합도(Coupling) & 응집도(Cohesion)

서론 소프트웨어 공학에서 모듈을 설계할 때에는 모듈의 독립성을 높은 수준으로 구현하여야 한다. 모듈(Module) : 시스템의 독자적인 기능으로 소프트웨어 성능 향상 및 재사용성을 높이기 위해

limsw.tistory.com

정리하면, 단일 책임 원칙(SRP)의 궁극적인 목적은 책임을 변경하는 이유는 오로지 1개 뿐이어야 한다는 것이다.

책임의 분할을 확실하게 해야 책임의 변경 시 다른 책임들이 영향을 받지 않을 수 있고, 더 견고하게 클래스를 설계할 수 있다.

이러한 설계가 바탕이 된다면 유지보수 및 코드의 가독성 또한 향상될 수 있다.

 

이론만으로는 해당 원칙의 설명이 부족할 수 있기 때문에 예제를 통해 SRP를 이해해보자.

단일 책임 원칙(SRP) 예제

class Book {
    String name;
    String author;
	
    // 생성자
    public Book(String name, String author) {
    	this.name = name;
        this.author = author;
    }
    
    public String getTitle() {
    	return name;
    }
    
    public String getAuthor() {
    	return author;
    }
    
    public void updateBook() {...}
}

Book이란 클래스의 3개의 함수는 다음과 같은 기능을 가지고 있다.

 

  • getTitle() : 책의 이름을 조회하는 기능
  • getAuthor() : 책의 저자를 조회하는 기능
  • updateBook() : 책의 대출 가능/불가 여부를 갱신하는 기능

이와 같은 3개의 기능이 있을 때 우리는 크게 액터를 다음과 같이 생각해볼 수 있다.

 

  • 책을 빌리기 위해 책의 정보를 조회는 고객 - getTitle, getAuthor 사용
  • 특정 책을 반납 가능 또는 불가 상태로 시스템에 갱신하는 관리자 - updateBook 사용

두 액터는 하는 기능(책임)이 완전히 다른 액터이다. 그러나 위처럼 하나의 Book 클래스 안에 2개 이상의 액터가 존재한다면 고객이 책의 대출 가능/불가 여부를 갱신하는 시스템에 원치 않게 건드릴 수도 있다.

 

따라서 위 클래스는 단일 책임 원칙을 위반한 경우가 되며, 이러한 경우 우리는 조회 기능시스템 접근 기능을 분리시켜야 SRP 원칙을 지킬 수 있다.

SRP 원칙을 적용한 코드

class Book {
    String name;
    String author;
	
    public Book(String name, String author) {
    	this.name = name;
        this.author = author;
    }
    
    public String getTitle() {
    	return name;
    }
    
    public String getAuthor() {
    	return author;
    }
}

class UpdateBookInfo {
	public void updateBook() {...}
}

다음 글에서는 SOLID 원칙의 O에 해당하는 개방 폐쇄 원칙(OCP)에 대한 개념을 알아볼 예정이다.

Comments