Program Language/java

인터페이스 네이밍은 어떻게 해야할까?

개발하는 주디씨 2023. 10. 10. 12:45

 

개발을 하다보면, service를 인터페이스로 만들어주고 implements해서 사용할 때가 많다. 그러나, 어느샌가부터 인터페이스를 만들고 단일 구현체를 만들어 기계처럼 코드를 작성해왔다는 생각이 들며 포스팅을 정리하게 되었다.

 

인터페이스 구현체  Impl 접미사는 지양해야한다

헝가리안 표기법의 잔재

학교나 단순한 코드 개발 등 생각보다 꽤 많은 곳에서 아직까지 이런 layout을 본 적이 있을 것이다. 인터페이스를 구현한 구현체에는 Impl 접미사가 붙은 걸 볼 수 있다. 이는 헝가리안 표기법의 잔재로, 지양해야 하는 표기법이다.

인터페이스 네이밍 방법

인터페이스를 네이밍할 때는 인터페이스의 이름을 그 의미 자체에 따라 지어야 한다.

예를 들어 전진go()), 후진(back()), 현재 위치 반환(getDistance())의 기능을 공통으로 갖는 자동차 클래스를 생성한다고 하자.

공통 기능인 전진, 후진, 현재 위치 반환을 각각의 클래스들이 갖고 있는 것은 객체지향적이지 못한 코드이다. 각 객체에서 중복되는 전진, 후진, 현재 위치 반환의 행위를 인터페이스로 추상화하는 것이 필요하다.

이때 인터페이스의 네이밍은 자동차의 움직임이라는 행위 자체로 네이밍을 해야한다는 것이다.

public class CarTest {

    public static void main(String[] args) {
        Move avante = new AvanteCar();
        Move porsche = new PorscheCar();
        avante.go();
        porsche.go();
        porsche.back();
        System.out.println("avanteCar = " + avante.getDistance());  // 10
        System.out.println("porscheCar = " + porsche.getDistance());  // 90
    }
}

interface Move {

    void go();

    void back();

    int getDistance();
}

class AvanteCar implements Move {

    private static final int GO_COUNT = 10;
    private static final int BACK_COUNT = 5;

    private int distance = 0;

    @Override
    public final int getDistance() {
        return this.distance;
    }

    @Override
    public final void go() {
        distance += GO_COUNT;
    }

    @Override
    public final void back() {
        distance -= BACK_COUNT;
    }
}

class PorscheCar implements Move {

    private static final int GO_COUNT = 100;
    private static final int BACK_COUNT = 10;

    private int distance = 0;

    @Override
    public final int getDistance() {
        return this.distance;
    }

    @Override
    public final void go() {
        distance += GO_COUNT;
    }

    @Override
    public final void back() {
        distance -= BACK_COUNT;
    }
}

추가로, Java Standard Library에서 List 인터페이스의 구현체인 ArrayList, LinkedList를 ArrayListImpl, LinkedListImpl이라고 명명하지 않는 것을 통해 헝가리안 표기법을 사용하지 않는다는 것을 다시 한 번 알 수 있다.

Impl과 같은 접미어는 DRY 규칙에도 어긋난다.

 

DRY 규칙

DRY 규칙이란

DRY 규칙은 Don’t Repeat Yourself의 약자로, ‘반복하지 마라’는 규칙이다.

DRY 규칙에 위배되는 네이밍 실수

앞에서 언급한 인터페이스의 구현체에 Impl 과 같은 접미사를 붙이는 행위처럼 DTO(Data Transfer Object)에 dto 접미사를 붙이는 실수를 많이 한다. 나 또한 지금까지 DTO에 해당 접미사를 붙였다. dto접미사를 붙이는 대신 패키지(package)에 넣음으로써 DRY 규칙을 따를 수 있다.

 

정리

만약 클래스 뒤에 Impl이라는 접미어를 붙일 수 밖에 없는 상황이라면, 인터페이스를 쓰는 것 자체에 대해 다시 생각해볼 필요가 있다. 인터페이스와 그것을 구현한 단 하나의 구현체만 있는 경우라면, 이런 경우에는 인터페이스를 쓰지 않는 것이 더 바람직할 수 있다. 지금 당장 작성했던 코드를 돌아보고 refactoring 해야겠다...

 

 

지금까지 당당하게 Impl을 붙인 내 과거가 부끄럽다

 

https://velog.io/@minide/Java-인터페이스Interface-네이밍