[OOP] SRP :: 단일책임원칙에 관하여

네,가능합니다 ㅣ 2024. 10. 15. 20:46

오늘은 특강으로 객체지향에 관한 내용을 배워서 객체지향에 관한 내용으로 TIL을 써볼까 한다.

그 중 코딩에 너무 집중해버리면 놓쳐버릴지 모르는 단일책임원칙에 관한 내용이다.

 

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

 

단일책임원칙은 객체지향 설계의 SOLID원칙 중 하나로, 클래스나 모듈이 단 하나의 책임만을 가져야 한다는 원칙이다.

 

여기서 "책임"이란 클래스가 변경될 이유가 하나뿐이어야 한다는 것을 의미한다고 한다.(이 말을 듣고 정말 많은 생각을 하게 되었다.)

 

SRP를 준수할 시 유지보수와 재사용성, 가독성이 좋아지고 책임이 명확히 나누어져 있어 클래스의 기능별 테스트도 매우 쉬워진다.

 

아래는 SRP위반 사례 및 적용 사례를 보여주겠다.

아니 이런것도 SRP에 위반이 된다고 ? 라는 생각이 들 정도이다.

 

public class Character
{
    public int health;
    public int mana;

    public void Move(float x, float y)
    {
        // 이동관련 코드
    }

    public void TakeDamage(int damage)
    {
        // 피격코드
        health -= damage;
    }

    public void Attack()
    {
        // 공격 코드
        mana -= 10;
    }

    public void PlaySound(string sound)
    {
        // 캐릭터 관련 사운드
    }
}

 

이렇게 코드를 작성했을때 문제점을 생각해보자.

 

협업을 할때 매우 불편하다. 캐릭터 스크립트를 담당하는 사람은 캐릭터의 모든것을 만들어야 할 지경이다..

 

또한 이 상태에서 업데이트를 한다던가 하면 코드가 너무 길어지고, 캐릭터 클래스에 너무 많은것들이 담아지게 돼 가독성도 떨어지게되며, 결국은 클래스 분리를 선택하고 말것이다.

 

아래는 SRP를 준수한 코드를 보여주겠다.

 

// 캐릭터의 이동 책임을 담당하는 클래스
public class CharacterMovement
{
    public void Move(float x, float y)
    {
        // 캐릭터 이동 코드
    }
}

// 캐릭터의 데미지 처리 책임을 담당하는 클래스
public class CharacterHealth
{
    public int health;

    public void TakeDamage(int damage)
    {
        // 캐릭터가 데미지를 받는 코드
        health -= damage;
    }
}

// 캐릭터의 공격 책임을 담당하는 클래스
public class CharacterAttack
{
    public int mana;

    public void Attack()
    {
        // 캐릭터가 공격하는 코드
        mana -= 10;
    }
}

// 캐릭터의 사운드 처리 책임을 담당하는 클래스
public class CharacterSound
{
    public void PlaySound(string sound)
    {
        // 캐릭터의 사운드를 재생하는 코드
    }
}

// 게임 캐릭터 클래스는 각 기능을 담당하는 클래스를 사용할 수 있습니다.
public class Character
{
    public string name;
    public CharacterMovement movement = new CharacterMovement();
    public CharacterHealth health = new CharacterHealth();
    public CharacterAttack attack = new CharacterAttack();
    public CharacterSound sound = new CharacterSound();
}

 

이렇게 단일책임 원칙을 적용한다면 생각나는 장점이 너무 많다.

 

협업에도 매우 유리하고, 다른 추가기능을 넣게 되더라도 다른 클래스에 별 다른 지장을 주지 않는다

예를 들면 공격이 아닌 마법공격이 추가되었으면 새로운 클래스를 만들어서 MagicAttack클래스에서 만들고 간단하게 추가해주어 사용하면 된다.

 

또한 어떤 한 기능에 문제가 생겼을때 이 문제가 여기저기 복잡하게 엮여있다면 연관이 있는 모든 코드를 수정해야 하지만

SRP를 준수했다면, 문제가 되는 부분만 수정하여 매우 안정적으로 문제해결이 가능하다.