본문 바로가기
Android/Kotlin

[Kotlin/Java] instanceof를 지양하자

by 일상 속 둔치 2023. 5. 5.

 

Java에서 instanceof 연산자는 객체가 특정 클래스의 instance인지를 확인하는데 사용된다.

아래처럼 실제 instance type을 알고 싶을 때에 사용할 수 있다.

class Parent{
}

class Child extends Parent{
}

Parent object = new Child();

if (object instanceof Child){ // object가 Child 인스턴스 형태인가?
}

실제로 프로그래밍 할 때 사용하면 정말 편하고 유용하지만 우리는 instanceof를 지양해야한다.

그 이유에 대해서 알아보자.

 

다형성 위배

우리는 다형성을 사용하여 같은 코드지만 실제 instance에 따라서 다르게 동작하도록 작성할 수 있다.

그리고 이를 위해서 변수 타입을 interface형으로 다루어 추상화를 시키고 있다.

 

그러나 다형성을 위해서 실제 구현을 모르게 숨겨놨는데, instanceof로 다시 확인/검색 하는 것은 다형성을 위배하는 것이며 코드만 복잡해진다.

* 아래처럼 코드가 작성 될텐데... 그러면 확장성도 떨어지게 된다. 새로운 class가 나올 때마다 조건이 늘어날테니...

if (obj instanceof MyClass1) {
    // do something for MyClass1
} else if (obj instanceof MyClass2) {
    // do something for MyClass2
} else if (obj instanceof MyClass3) {
    // do something for MyClass3
} else if (obj instanceof MyClass4) {
    // do something for MyClass4
} else {
    // do something else
}

 

다형성 이외에도 Solid 원칙 중 OCP/SRP에 대해서도 문제가 발생할 수 있다.

 

SRP (Single Responsibility Principle)

모든 클래스는 단 하나의 책임을 가진다는 원칙이다.

그러니까 예를 들어, 위의 코드에서 MyClass를 참조하는 클래스에서 instaceof를 통해 동작을 구분하게 된다.

그렇게 되면 MyClass에 대한 동작을 참조하는 쪽에서 지정/수행하는 것처럼 될 수 있다.

SRP를 위배하지 않으려면 MyClass에 선언된 동작으로 동작하게 수행해야한다.

 

OCP (Open Closed Principle)

확장에 대해서는 개방 되어 있어야 하지만, 수정에 대해서는 폐쇄 되어야 한다는 원칙이다.

다형성 위배에서 언급하긴 했지만... 새로운 Class가 추가될 때마다 instanceof로 구분하는 코드가 추가 되어야한다.

객체가 확장되거나 추가될 때마다 더 많은 소요/비용이 필요해지게 되어 OCP를 위반할 수도 있다.

 

 

그래서 instanceof를 지양해야 하는데 해당 기능이 필요한 경우 어떤 식으로 사용할 수 있을까?

 

대안책

서브 클래스에 isType() 형식으로 추상 메소드를 선언하는 방식으로 해볼 수 있다.

class Parent{
  public abstract boolean isChild();
}

class Child extends Parent{

  @Override
  public boolean isChild(){
    return true;
  }
}

사실 이렇게 보면 결국 instanceof로 작성하던 내용을 isChild로 확인하는 것이라 뭐가 다른가 싶을 수도 있다.

하지만 확인하는 주체와 책임이 참조하는 쪽이 아닌 서브 클래스 쪽에 있다는 점에 있어서 좀 더 보완적인 코드라고 할 수 있다.

'Android > Kotlin' 카테고리의 다른 글

3. 반복문, 조건문  (0) 2018.12.31
2. 함수  (0) 2018.12.31
1. 클래스  (0) 2018.12.25
[Intro] 안드로이드 공식언어?  (0) 2018.12.25

댓글