Software Develop/개발이론

SOLID원칙 - ISP(Interface Segregation Principle)

jaywapp 2023. 1. 16. 21:39

ISP(Interface Segregation Principle)이란?

특정 클라이언트가 자신이 이용하지 않는 메서드 등의 멤버에 의존하면 안된다.

ISP(Interface Segregation Principle)은 직역하면 인터페이스 분리 원칙이다. 다시 말하자면 특정 객체가 특정 인터페이스를 상속받아 구현할 때 불필요한 메서드나 멤버가 있으면 안된다는 원칙이다.

 

스마트폰에 빗대서 설명해보자.

 

아래에 SmartPhone의 기능을 정의한 인터페이스가 있다. 스마트폰처럼 음악을 재생시킬 수 있고 메세지, 전화 기능도 구현되어 있으며 검색 기능까지 구현되어 있다.

public interface ISmartPhone
{
    void PlayMusic();
    void SendMessage();
    void Call();
    void Search();
}

이를 상속받아 SmartPhone이라는 객체를 구현한다면 아무런 문제가 없을 것이다. 하지만 전화기과 컴퓨터, 뮤직플레이어가 이를 상속받아 구현한다면 어떨까?

public class TelePhone : ISmartPhone
{
    public void Call() 
    {
        // 전화 기능 구현
    }

    public void SendMessage() 
    {
        // 메세지 기능 구현
    }

    public void PlayMusic() 
    {
        // 미구현
    }

    public void Search() 
    {
        // 미구현
    }
}

public class Computer : ISmartPhone
{
    public void Search()
    {
        // 검색 기능 구현
    }

    public void Call()
    {
        // 미구현
    }

    public void SendMessage()
    {
        // 미구현
    }

    public void PlayMusic()
    {
        // 미구현
    }
}

public class MusicPlayer : ISmartPhone
{
    public void PlayMusic()
    {
        // 음악 재생 기능 구현
    }

    public void Call()
    {
        // 미구현
    }

    public void SendMessage()
    {
        // 미구현
    }

    public void Search()
    {
        // 미구현
    }
}

 

위처럼 ISmartPhone 인터페이스를 상속받고 각각 구현가능한 함수만 구현되었다고 하자.

외부에서 TelePhone, Computer, MusicPlayer 객체를 사용할 때, 의미에 맞게 사용할 수 있을까?

ISmartPhone 인터페이스에서는 정의가 되어 있지만 실제 객체에서는 구현되지 않은 메서드가 존재할 수 있다.

 

ISP 원칙을 적용해보자. ISP 원칙에 따르면 TelePhone은 전화에 대한 메서드만 정의된 인터페이스를 상속받아야 한다. Computer, MusicPlayer 객체도 각각 마찬가지이다. 그렇다면 ISmartPhone 인터페이스를 분리하여 구조를 만들 필요가 생긴다.

public interface ITelePhone
{
    void SendMessage();
    void Call();
}

public interface IComputer
{
    void Search();
}

public interface IMusicPlayer
{
    void PlayMusic();
}

위 코드처럼 ISmartPhone 인터페이스를 의미에 따라 ITelePhone, IComputer, IMusicPlayer로 분리하였다. 이렇게 되면 TelePhone, Computer, MusicPlayer 객체를 구현함에는 결함이 없다. 다만 SmartPhone 객체를 구현할 때에는 이전과 다르게 구현되어야 한다. 즉, 분리된 인터페이스를 모두 상속받아 SmartPhone 객체를 구현한다.
(혹은 ISmartPhone을 구현하되, ITelePhone, IComputer, IMusicPlayer을 상속받아 구현한다.)

public class SmartPhone : ITelePhone, IComputer, IMusicPlayer
{
    public void Call() { }

    public void PlayMusic() { }

    public void Search() { }

    public void SendMessage() { }
}

 

위와 같이 구현된다면 각 객체에서는 불필요하게 의존하는 메서드가 없어지며 외부에서 인터페이스만으로 각 객체에 대한 제어가 가능해진다.