1. 인터페이스에 대고 프로그래밍 하기(Program to interface)
객체 지향의 유명한 규칙 중 다음과 같은 규칙이 있습니다. "인터페이스에 대고 프로그래밍 하기(program to interface)" 즉, 이 말은 실제 구현을 제공하는 콘크르티 클래스(구현 클래스)를 사용해서 프로그래밍 하지 말고, 기능을 정의한 인터페이스를 사용해서 프로그래밍하라는 뜻 입니다.
그런데, 인터페이스는 최초 설계에서 바로 도출되기 보다는, 요구 사항의 변화와 함께 점진적으로 도출이 됩니다.
'상속과 다형성 2' 글에서 다루었던 FlowController의 경우도 파일이 아닌 소켓에서도 데이터를 읽어 와야 한다는 새로운 요구 사항이 추가 되면서, ByteSource라는 인터페이스가 도출 되었습니다.
추상 타입을 사용하면 기존 코드를 건드리지 않으면서 콘크리트 클래스(구현 클래스)를 교체 할 수 있는 유연함을 얻을 수 있었는데, '인터페이스에 대고 프로그래밍 하기(program to interface)' 규칙은 바로 추상화를 통한 유연함을 얻기 위한 규칙 입니다.
주의할 점은 유연함을 얻는 과정에서 타입(추상 타입)이 증가하고 구조도 복잡해지기 때문에 모든 곳에서 인터페이스를 사용해서는 안된다는 것입니다. 이 경우, 불필요하게 프로그램의 복잡도만 증가 시킬 수 있습니다. 인터페이스를 사용해야 할 때는 변화 가능성이 높은 경우에 한해서 사용해야 합니다.
인터페이스라는 것은 추상화 과정을 통해서 도출되는데, 이 추상화 과정은 변화가 발생하는 곳에서 부터 시작 됩니다. 따라서, 변화 가능성이 높은 콘크리트 클래스(구현 클래스) 대신 이를 추상화한 인터페이스를 사용하면, 다소 구조는 복잡해지지만, 변경의 유연함 이라는 효과를 얻을 수 있습니다. 반대로, 변경 가능성이 매우 희박한 클래스에 대해 인터페이스를 만든다면 오히려 프로그램의 구조만 복잡해지고 유연함의 효과는 누릴 수 없는 그런 상황이 발생하게 됩니다.
2. 인터페이스 이름은 인터페이스를 사용하는 입장에서 만들기
'상속과 다형성 2' 글 에서 FileDataReader만 필요한 상황에서 향후 구현 변경의 유연함을 얻기 위해, 만약 아래 그림과 같이, FileDataReaderIF라는 인터페이스를 만들었습니다.
이 상태에서 소켓을 이용해서 데이터를 읽어 오는 기능이 필요하다면 어떻게 될까? 이 경우 아래 그림과 같은 구조를 갖게 됩니다. 하지만, FlowController 입장에서는 FileDataReaderIF 라는 이름 때문에, 이 인터페이스를 상속 받아 구현한 클래스는 모두 '파일'로 부터 데이터를 읽어 온다고 착각하기 쉽습니다.
따라서, 인터페이스 이름을 작성 할 때에는 그 인터페이스를 사용하는 코드 입장에서 이름을 작성해야 합니다. 이 예제 에서는 FlowController 입장에서 인터페이스 이름을 작성해야 합니다. 파일, 소켓, HTTP를 통해 데이터를 읽어 올 수 있는 상황 이므로, FileDataReaderIF라는 이름 보다, ByteSource라는 이름을 사용하는 것이 의미를 더 명확하게 드러낼수 있습니다.
'Java' 카테고리의 다른 글
가비지 콜렉션 (Java 가상 머신의 메모리 영역) (0) | 2022.11.09 |
---|---|
Gson Expose 어노테이션 (2) | 2021.01.05 |
상속과 다형성 2(추상 타입을 이용한 구현 교체의 유연함) (0) | 2020.11.05 |
상속과 다형성 1 (0) | 2020.11.04 |