📌
특정 코드를 짜는 과정에서 전체가 아닌 일부에만 속하는 타입을 확인하기 위해 불가피하게 instanceof 연산자를 사용하게 되었다
instanceof 연산자가 좋지 않다고만 어렴풋이 알고 있었기에 글을 작성한다.
instanceof 연산자란?
- A가 B의 인스턴스인지 판단할 때 A instanceof B 의 형태로 사용되며 반환 값은 boolean이다.
어떤 상황에서 주로 사용하는가
- 하나의 타입이 하나의 인스턴스만 가지는 경우에는 사용할 일이 많이 없다.
- 그러나 하나의 타입이 여러 인스턴스를 가지는 경우에 사용할 수 있다.
- 주로 상속 및 인터페이스를 통한 다형성을 가지게 될 경우에 사용할 수 있다.
그러나
void move(int position, Vehicle vehicle) {
if (vehicle instanceof Bus){
position += 30;
} else if (vehicle instanceof Bycicle) {
position += 3;
} else if (vehicle instanceof Motorcycle){
position += 10;
}
}
void move(Vehicle vehicle) {
vehicle.move();
}
캡슐화 및 추상화를 깨뜨린다.
- 위 예시처럼 instanceof를 사용한다는 의미는 추상화와 캡슐화를 지키지 못한다는 뜻이다 상위 클래스를 사용하는 메소드 내에서 하위 클래스 내부가 어떻게 동작하는지 전혀 알 필요가 없다. 따라서 추상화를 통해 instanceof를 대체한다.
LSP를 위반한다.
- instanceof 키워드를 사용한다는 것 자체가 상위 객체를 하위 객체로 완벽히 치환할 수 없기 때문에 사용하게 되는 것이다.
OCP를 위반한다.
- instanceof 연산자를 사용하게 되면 예시 코드에서 추가적인 이동 수단이 생겨날 때마다 다른 코드를 수정해야한다.
SRP를 위반한다
- instanceof 키워드를 사용한 메소드를 보면 Bus, Bycicle, Motorcycle의 움직임에 대한 책임을 지고 있다. 이동 수단이 많아질 수록 더욱 많은 책임을 갖게 된다. 이에 대한 책임을 각 클래스가 갖도록 분산해 주어야 할 필요가 있다.
성능이 비효율적이다.
- 다형성을 적용하여 구현하면, 컴파일러는 가상 메서드를 바로 호출한다.
- 그러나 instanceof 사용시
- 알맞은 타입을 찾기 위해 모든 타입을 검사하고, 그로 인하여 성능이 저하된다.
- 확인할 객체가 많아질 수록 성능의 차이는 더욱 커지게 된다.
💡
성능을 위해서든, 객체 지향적 코드를 위해서든, instanceof 사용은 가능한 지양하자.
대신 추상화와 캡슐화를 적극적으로 활용하자
출처