본문 바로가기
개발용어

SOLID 원칙 - 인터페이스 분리 원칙, ISP (Interface Segregation Principle)

by devscb 2022. 5. 11.
반응형

SOLID 원칙 - 인터페이스 분리 원칙, ISP (Interface Segregation Principle)


인터페이스 분리 원칙이란? (ISP, Interface Segregation Principle)



인터페이스 분리 원칙은 "클라이언트는 자신이 사용하지 않는 메소드에는 의존하지 않아야된다"라는 의미로 사용되는 원칙입니다.
인터페이스나, 상속을 하였는데, 사용하지 않는 메소드가 있다면 분리를 해줘야 한다는 원칙입니다.
이 원칙이 지켜지면 무슨 이점이 있는지 바로 코드 예제로 살표보겠습니다.


ISP 를 준수하지 않는 코드의 예




interface Machine{
 string name;
 int showCurrentTime();
 int playMP3(string path);
 int calculateAdd(int a, int b);
}

class MP3player implements Machine{
 MP3Player(){
 this.name = "MP3player";
 }
 
 @override
 int showCurrentTime(){
 System.out.print(currentTime());
 }
 @override
 int playMP3(string path){
 System.out.print("play : "+path);
 }
 @override
 int calculateAdd(int a, int b){
 throw new Exception("unsupported");
 }
}


class Clock implements Machine{
 Clock(){
 this.name = "Clock";
 }
 
 @override
 int showCurrentTime(){
 System.out.print(currentTime());
 }
 @override
 int playMP3(string path){
 throw new Exception("unsupported");
 }
 @override
 int calculateAdd(int a, int b){
 throw new Exception("unsupported");
 }
}


class Calculator implements Machine{
 Calculator(){
 this.name = "Calculator";
 }
 
 @override
 int showCurrentTime(){
 throw new Exception("unsupported");
 }
 @override
 int playMP3(string path){
 throw new Exception("unsupported");
 }
 @override
 int calculateAdd(int a, int b){
 System.out.println(a+b);
 }
}



위 코드에서 MP3Player, Clock, Calculator는 Machine이라는 클래스를 상속하고 있는데요,
각 클래스는 Machine에서 사용하지 않는 메소드를 오버라이딩을 해야하는 의무가 있습니다.
오버라이딩시, 이를 지원하지 않기 위해 exception을 처리하도록 하였습니다.
불필요함에도 불구하고 exception을 처리해줘야 하는 불편함이 있기에 사용하지 않는 메소드를 구현하지 않도록 인터페이스를 분리해주어야 합니다.

또한 아래와 같이 Phone이라는 class를 추가하기 위해 Machine에 call() 메소드를 추가한다면 어떻게 될까요?
아래와 같이 Machine에 call()메소드를 추가해주고,
이 인터페이스를 사용하던 MP3Player, Clock, Calculator 클래스들에서도 각각 이 메소드에 대해 override 하고 exception 코드를 작성해주어야겠지요.
또한, 각각의 클래스를 재 컴파일 해야하서 빌드타임이 증가할 수 밖에 없습니다.



class Phone implements Machine{
 Phone(){
 this.name = "Phone";
 }
 @override
 int call(){
 System.out.println("calling...");
 }
 
 @override
 int showCurrentTime(){
 System.out.print(currentTime());
 }
 ...
}

interface Machine{
 string name;
 int showCurrentTime();
 int playMP3(string path);
 int calculateAdd(int a, int b);
 int call();
}





ISP 준수하도록 개선하기


ISP는 자기가 사용하지 않는 method는 분리하자 입니다.
method를 각자 분리한다면 아래와 같이 개선할 수 있겠지요.


interface Machine{
 string name;
}

interface MP3playable{
 int playMP3(string path);
}

interface showTimeMachiine{
 int showCurrentTime();
}

interface Calculatable{
 int calculateAdd(int a, int b);
}

class MP3Player implements Machine, MP3Playable, showTimeMachiine{
 //calculateAdd를 구현하지 않아도 됨.
}

class Calculator implements Machine, Malculatable{
 //playMP3, showCurrentTime 구현하지 않아도 됨.
}

...



위와 같이 불필요한 method를 추가하지 않아도 되겠지요.
또한, phone을 구현하기위해 Machine 인터페이스를 변경하지 않아도 되므로,
이전에 컴파일했었던 MP3Player, Calculator 클래스 등은 다시 컴파일 하지 않아도 되므로
빌드시간도 현격히 줄어들 수가 있겠지요.


총평


ISP는 각자가 구현해야하는 일에만 충실해야한다는 점에서 SRP와 상통하는 원칙이라고 볼 수도 있습니다.
SRP를 잘 지키는것부터 연습을 해보면 ISP를 잘 준수할 수 있지 않을까 싶습니다.
가능한 interface를 기능별로 잘 그룹화하여 분리하고 기능별로 잘 묶을 수 있도록 계속해서 고민한다면
ISP를 지켜 전체 빌드시간도 절약하고, 코드 수정하는 부분도 많이 개선하여 유지보수 비용을 크게 개선할 수 있을 것입니다.


#SOLID,#SOLID원칙,#인터페이스,#분리,#원칙,#SOLIDprinciple,#ISP,#인터페이스분리원칙,#interface,#segregation,#principle


https://devscb.com/post/97

 

SOLID Principle - Interface Segregation Principle, ISP (Interface Segregation Principle)

SOLID Principle - Interface Segregation Principle, ISP (Interface Segregation Principle) What is the interface separation principle? (ISP, Interface Segregation Principle)The Interface Separation Prin

devscb.com

 

728x90
반응형

댓글