Unity/C#

[C#] SOLID 원칙 : 단일 책임 원칙(SRP)

HungryK 2025. 3. 6. 22:57

 

공부용으로 작성되는 페이지입니다. 틀린 부분이나 환경에 따라 오류가 발생할 수 있습니다. 

 

객체 지향을 접하면서 몇 번이고 들어본 SOLID 원칙, 머리로는 알고 있는데 잘 익혔는지는 모르겠다.  

따라서 하나하나 포스트로 정리하며 공부해볼 예정이다. 


 

0. SOLID 원칙?

SOLID 원칙이란 객체지향 설계에서 지켜줘야 할 5개의 소프트웨어 개발 원칙( SRP, OCP, LSP, ISP, DIP )을 말한다.

결국 '좋은 객체지향 설계'를 위해서 지켜야할 원칙들이므로, 디자인 패턴을 공부하기 전 하나하나 복습하려한다. 

 

  • SRP(Single Responsibility Principle): 단일 책임 원칙
  • OCP(Open Closed Priciple): 개방 폐쇄 원칙
  • LSP(Listov Substitution Priciple): 리스코프 치환 원칙
  • ISP(Interface Segregation Principle): 인터페이스 분리 원칙
  • DIP(Dependency Inversion Principle): 의존 역전 원칙

 

1. 단일 책임 원칙 (SRP) 개념 

단일 책임 원칙이란?

 

클래스(객체)는 단 하나의 책임만 가져야한다는 원칙이다. 즉, 하나의 클래스가 하나의 기능을 수행하도록 클래스를 따로 설계해야한다는 의미다. 클래스가 제공하는 모든 기능은 하나의 책임을 수행하는데 집중해야한다. 해당 원칙은 클래스간 의존성을 낮춰 한 클래스의 변경을 자유롭게 만들어 유지 보수에 초첨을 맞춘것이다. 

 

결국 A의 기능이 변경되었을 때 B,C,D까지 수정해야한다면 SRP가 지켜지지 않았다고 볼 수 있다. 

즉, 기능을 수정하였을 때 파급 효과를 생각해야한다. 

 

단일 책임 원칙의 예시 

하나의 클래스에는 하나의 기능(책임)만을 담당해야한다. 사례를 하나 생각해보자. 

 

단일 책임 원칙을 위 생각할 것 

  • 하나의 클래스는 하나의 기능을 담당하고 수행해야한다. 
  • 책임 영역을 확실하게 한다, 이를 위해 여러 개의 클래스를 사용하는 것이 효율적이다. 
    • 클래스 작명시 책임의 소재를 알 수 있게 명확하게 작성 
  • 하나의 책임이 변경되더라도 다른 책임이 변경되지 말아야한다. ex) A 기능 수정 시 B 기능 수정도 되면 안 된다. 

 

2. 단일 책임 원칙 (SRP)  사례 

SRP가 지켜지지 않은 케이스 

 

유니티에서 게임을 만들다보면 흔히 singleton 기반 'GameManager'를 만들게 된다. (싱글톤은 추후 작성 예정)

GameManager에 일정한 규칙이 있는 것은 아니지만 흔히 점수나 전체적은 게임의 플로우를 담당한다.

하지만 아래와 같은 GameManager은 SRP를 어기고 있다. 

 

public class GameManager
{
    private static GameManager instance;
    public static GameManager Instance => instance ?? (instance = new GameManager());

    public int Score { get; private set; }
    
    public void AddScore(int points) { Score += points; }
    public void SaveGame() { /* 게임 데이터 저장 */ }
    public void LoadGame() { /* 게임 데이터 로드 */ }
    public void ShowGameOverUI() { /* 게임 오버 UI 표시 */ }
}

 

해당 게임 매니저의 함수를 한 번씩만 읽어보아도 점수, 데이터 관리(저장 및 로드), UI 등 여러가지 역할을 수행하고 있음을 알 수 있다. 특히 싱글턴 기반 Manager은 전역에서 접근이 가능하다는 특징때문에 지나치게 책임을 부여하는 실수를 저지르기 쉽다.

 

SRP가 지켜진 케이스 

 

해당 케이스에서는 위에서 언급한대로 책임에 따라 여러 클래스로 구분하여 SRP를 지켜주었다.

 

#점수 기능(책임)

public class ScoreManager
{
    private static ScoreManager instance;
    public static ScoreManager Instance => instance ??= new ScoreManager();

    public int Score { get; private set; }

    public void AddScore(int points)
    {
        Score += points;
    }
}

 

#데이터 기능(책임)

public class SaveManager
{
    private static SaveManager instance;
    public static SaveManager Instance => instance ??= new SaveManager();

    public void SaveGame() { /* 게임 데이터 저장 */ }
    public void LoadGame() { /* 게임 데이터 로드 */ }
}

 

 

 

참고 자료 

 

 

💠 객체 지향 설계의 5가지 원칙 - S.O.L.I.D

객체 지향 설계의 5원칙 S.O.L.I.D 모든 코드에서 LSP를 지키기에는 어려움. 리스코프 치환 원칙에 따르면 자식 클래스의 인스턴스가 부모 클래스의 인스턴스를 대신하더라도 의도에 맞게 작동되어

inpa.tistory.com

 

 

💠 완벽하게 이해하는 SRP (단일 책임 원칙)

단일 책임 원칙 - SRP (Single Responsibility Principle) 단일 책임 원칙(SRP)는 객체는 단 하나의 책임만 가져야 한다는 원칙을 말한다. 여기서 '책임' 이라는 의미는 하나의 '기능 담당'으로 보면 된다. 즉,

inpa.tistory.com

(해당 게시물이 설명과 예시가 굉장히 좋으므로, 공부중이라면 꼭 읽어보길 권장)