[OOP] instanceof의 사용을 지양하라
instanceof?
instanceof는 인스턴스의 타입을 확인하는데 사용하는 연산자이다.
즉, 다음과 같은 형식으로 사용할 수 있다. 다음은 car이 Avante에 해당하는지 체크하는 조건문이다.
if (car instanceof Avante) {
System.out.println("is Avante");
}
instanceof의 사용을 지양하라?
유용해보이는데 왜 지양하라고 하는 것일까?
객체지향적이지 못하기 때문이다. instanceof 보다는 다형성을 활용하여 작성하는 것이 권장되는데, 그 이유가 무엇일까?
다형성 vs instanceof
다형성
interface Car {
void operate();
}
class Avante extends Car {
public void operate() {
System.out.println("Avante");
}
}
class Sonata extends Car {
public void operate() {
System.out.println("Sonata");
}
}
class Grandeur extends Car {
public void operate() {
System.out.println("Grandeur");
}
}
public class Main {
public void operate(Car car) {
car.operate();
}
}
instanceof
public class Main {
public void operate(Car car) {
if (car instanceof Avante) {
System.out.println("Avante");
} else if (car instanceof Sonata) {
System.out.println("Sonata");
} else if (car instanceof Grandeur) {
System.out.println("Grandeur");
}
}
}
캡슐화
그 첫 번째 이유는 OOP의 특징인 캡슐화에 있다.
캡슐화는 클래스 안에 서로 연관있는 속성과 기능들을 하나의 캡슐로 만들어 데이터를 외부로부터 보호하는 것을 말한다. 즉, 객체가 가진 상태나 행위를 다른 이가 사용하거나 보지 못하도록 숨기는 것이다.
하지만 instanceof를 사용할 경우, 외부에서 각 객체가 무엇이고 어떤 행위를 하도록 구성되어 있는지 다 알 수 있게 된다.
이 때문에 캡슐화가 깨지고 객체지향적이지 못하게 된다.
개방 폐쇄의 원칙 (OCP)
개방 폐쇄 원칙은 확장에는 열려있고 변경에는 닫혀있어야 한다는 객체 지향 원칙이다. 하지만 instanceof를 사용하게 되면 그렇지 못하게 된다.
예를 들어, 여기서 Car를 상속하는 Ioniq이라는 클래스가 새로 추가됐다고 해보자.
다형성을 이용하면 새로 생성한 Ioniq 클래스에 해당 기능을 구현하면 되는 반면에 instanceof를 사용하는 경우 새로운 메서드를 만들어주기 위해 사용되는 곳에 가서 모두 고쳐주어야 한다.
이렇게 됨으로써 개방 폐쇄 원칙이 깨지고 객체지향적이지 못한 코드가 된다.
단일 책임 원칙(SRP)
단일 책임 원칙은 객체는 단 하나의 책임만 가져야 한다는 원칙이다.
위에서 instanceof를 사용한 코드를 살펴보면 instanceof로 타입을 체크하고 각 클래스들(Avante, Sonata, Grandeur)의 행위를 한 메서드에 구현하고 있다. 반면 다형성을 활용한 코드는 각 클래스가 스스로 부여된 책임을 갖고 행동하도록 되어있다.
때문에 위 코드는 instanceof를 사용함으로써 단일 책임 원칙이 위반되었다고 볼 수 있다.
성능
Avante, Sonata, Grandeur이 서로 다른 구현이 필요한 경우에 다형성을 활용하여 구현하면 컴파일러는 어떤 타입의 메서드를 실행해야할지 알 수 없으므로 invokevirtual 바이트코드를 이용해 메서드에 대한 가상의 호출을 한다.
이후 런타임에 특정 타입을 찾아 그에 맞는 구현을 실행한다.
반면, instanceof의 경우 알맞은 타입을 찾을 때까지 컴파일 시 모든 타입을 돌며 검사해야한다.
이 때문에 다형성을 활용한 코드의 성능이 instanceof를 사용한 코드보다 빠르다.
마무리
Java 개발자라면 객체지향을 지키며 작성해야 코드도 깔끔해지고 유지보수가 수월해진다.
모두 살아있는 코드를 작성하기 위해 기본적인 객체지향을 지키며 개발해나가는 노력이 필요하다.
'Software Engineering > OOP' 카테고리의 다른 글
[OOP] 무분별한 Getter/Setter를 지양하라 (0) | 2023.03.16 |
---|---|
[OOP] 원시 타입을 포장하라 (0) | 2023.03.15 |
[OOP] 상속보다는 조합을 사용하자 (0) | 2023.03.15 |
댓글
이 글 공유하기
다른 글
-
[OOP] 무분별한 Getter/Setter를 지양하라
[OOP] 무분별한 Getter/Setter를 지양하라
2023.03.16 -
[OOP] 원시 타입을 포장하라
[OOP] 원시 타입을 포장하라
2023.03.15 -
[OOP] 상속보다는 조합을 사용하자
[OOP] 상속보다는 조합을 사용하자
2023.03.15