간결하게 말하자면, '하나의 객체는 반드시 하나의 동작만의 책임을 갖는다'는 원칙이다.
모듈화가 강할수록 다른 객체와의 의존 및 연관성이 줄어들며 모듈화가 약할수록 다른 객체와의 의존 및 연관성이 늘어난다.
약한 모듈화는 정보 은닉화가 되지 않기 때문에 모듈의 메소드에 무분별하게 접근할 수 있게 되므로 모듈의 의존성을 지양해야한다.
모듈화가 약할 때 코드가 무분별하게 길어지거나 복잡해지면, 코드 수정할 때마다 전체적으로 대공사를 해야하는 번거로움이 생긴다.
이를 방지하기 위해 '단일 책임 원칙', 즉 객체 하나 당 책임도 하나만 줌으로써 책임을 줄여줘서 최대한 간결하게 코드 작성을 할 수 있게 해준다.
class Character
{
protected string name;
public string Name { get => name; set => name = value; }
public Character(string name, float hp)
{
//this.name = name;
//this.hp = hp;
Name = name;
Hp = hp;
}
public override string ToString() => $"{name}, {hp}";
public virtual void Move() //[추상성 - 가상화] 부모가 가상화 되어야 오버라이딩 가능. 키워드 : virtual
{
Debug.Log("Charater : 우측 방향 > 10만큼 이동");
}
}
class Player : Character
{
public Player()
: base("None", -1) //base() : 부모 클래스
{
Debug.Log(ToString()); //부모한테 상속받음
}
public Player(string name, float hp)
: base(name, hp) //base() : 부모 클래스
{
Debug.Log(ToString());
}
public override void Move() //자식의 필요에 의해서 재정의. 키워드 : override
{
base.Move(); //부모의 Move() 사용
Debug.Log("Player : 전진 > 30만큼 이동");
}
}
class Monster : Character
{
public Monster(string name, float hp)
:base(name, hp)
{
Debug.Log($"Monster {ToString()}");
}
public override void Move() //Move() 재정의
{
Debug.Log("Monster : 후진 > 50만큼 이동");
}
}
→ Character
클래스를 상속 받은 Player
, Monster
클래스는 각자의 Move()
함수에 알맞은 동작을 구현하여 한 객체가 하나의 책임을 갖게 된다.
예를 들어 Monster
의 이동에 관련하여 코드를 수정해야한다면, 부모 클래스인 Character
의 코드는 변경하지 않고 해당 객체의 메소드만 수정하면 되므로 의존성이 현저히 떨어지기 때문에 올바른 모듈화가 된다.