네 번째 SOLID 원칙인 인터페이스 분리 원칙에 대해서 예제를 통해 이해해 보도록 하겠습니다.
인터페이스 분리 원칙(ISP)의 이해와 예제
인터페이스 분리 원칙이란
인터페이스를 사용할 때 가능한 적은 인터페이스를 사용해야 한다는 원칙입니다. 거대한 인터페이스를 사용한다면 해당 인터페이스에서 사용 불가능하거나 의미 없는 인터페이스까지 사용할 수 있고 의존하게 되므로 불안정한 코드가 되거나 가독성에 좋지 않습니다.
따라서 꼭 필요한 전용 인터페이스를 사용하는 것을 선호해야 합니다.
2023.01.14 - [개발/개발 공통] - [객체 지향] SOLID 원칙에 대해서 알아보자
예제
예제는 이전 리스코프 치환 원칙에서 활용했었던 새의 경우를 들어보겠습니다.
Bird라는 클래스는 fly, swim, eat 라는 세 가지 메서드를 가진 인터페이스 클래스입니다.
이때 eagle와 penguin이 Bird를 상속받는다면, eagle는 swim을 못하고, penguin은 fly를 못하기 때문에 각 객체마다 예외적인 상황이 존재하게 되어 이해하기 어려운 코드가 될 수 있습니다.
이런 경우가 바로 인터페이스 분리 원칙을 위배했다고 볼 수 있습니다.
#include <iostream>
using namespace std;
class Bird
{
virtual string fly() = 0;
virtual string swim() = 0;
virtual string eat() = 0;
};
class eagle : public Bird
{
string fly() override
{
return "can fly";
}
string swim() override
{
return "can not swim";
}
string eat() override
{
return "can eat";
}
};
class penguin : public Bird
{
string fly() override
{
return "can not fly";
}
string swim() override
{
return "can swim";
}
string eat() override
{
return "can eat";
}
};
따라서 이런 경우를 개선하기 위해서는 인터페이크 클래스인 Bird를 분리할 필요가 있습니다.
적절할지는 모르겠지만 BirdCanNotSwim 이라는 인터페이스 하나와 BirdCanNotFly라는 인터페이스로 분리합니다.
eagle의 경우 BirdCanNotSwim을 상속받고 penguin의 경우 BirdCanNotFly 라는 인터페이스를 상속받아서 각각 적절한 인터페이스만을 사용하도록 수정합니다.
이렇게 되면 eagle->swim() 이나 penguin->fly()와 같은 메서드가 컴파일 타임에 원칙적으로 차단되므로 안전하고 명확한 코드를 작성할 수 있게 됩니다.
#include <iostream>
using namespace std;
class BirdCanNotSwim
{
virtual string fly() = 0;
virtual string eat() = 0;
};
class BirdCanNotFly
{
virtual string swim() = 0;
virtual string eat() = 0;
};
class eagle : public BirdCanNotSwim
{
string fly() override
{
return "can fly";
}
string eat() override
{
return "can eat";
}
};
class penguin : public BirdCanNotFly
{
string swim() override
{
return "can swim";
}
string eat() override
{
return "can eat";
}
};
결론
인터페이스 분리 원칙은 자칫 과하게 남용하면 인터페이스가 너무 세분화되거나 오히려 가독성에 안 좋아질 수 도 있을 것 같습니다. 모든 원칙이 그렇듯 정답이 있는 건 아니고 각각의 원칙을 이해하고 상황에 맞게 적절하게 활용하여 리팩토링 하는 게 중요하다고 할 수 있겠습니다.
'개발 > 개발 공통' 카테고리의 다른 글
[Design Pattern] Composite 패턴 (0) | 2024.02.23 |
---|---|
[객체지향 SOLID 원칙] 의존성 역전 원칙(DIP)의 이해와 예제 (0) | 2023.05.26 |
[객체지향 SOLID 원칙] 리스코프 치환 원칙(LSP)의 이해와 예제 (0) | 2023.05.26 |
[객체지향 SOLID 원칙] 개방 폐쇄 원칙(OCP)의 이해와 예제 (0) | 2023.05.26 |
[객체지향 SOLID 원칙] 단일 책임 원칙(SRP)의 이해와 예제 (0) | 2023.05.26 |