본문 바로가기

기타/객체지향 토막글

인터페이스 - 수필 객체지향

인터페이스(Interface)는 산의 맑은 공기와 같다. 등산할때는 항상 맑은 공기를 마실 수 있지만, 맑은 공기의 고마움은 쉽게 인식하지 못한다. 등산을 마치고 도시속에 찌든 공기를 마시고 기침을 콜록일 때서야 그 고마움을 깨닫곤 한다.

인터페이스는 바다의 해삼과 같다. 해삼은 인간에게 가장 이로운 영양을 주는 해산물로, 해녀가 깊은 바닷속에 잠수해야 겨우 몇마리 건져올리는 해산물이다.

인터페이스는 산의 맑은 공기처럼 늘 객체지향 개발자와 함께 하는 존재이며, 무의식중에 쓰이는 존재이지만, 인터페이스의 고마움을 쉽게 인식하지 못한다. 개발을 마치고 어지럽기만한 코드를 디버깅 하다가 인터페이스 형식으로 리팩토링 해서야 그 고마움을 깨닫곤 한다.

인터페이스는 바다의 해삼처럼 객체지향 요소 중에서 개발자에게 가장 이로운 결과물을 주는 요소로, 객체지향 개발자가 깊이있게 생각해야, 모든 자식 클래스를 아우르는 추상 인터페이스로 겨우 건져올리곤 한다.


인터페이스는 산의 맑은공기와 바다의 해삼처럼 객체지향의 유익한 요소, 객체지향의 정수이며 객체지향의 꽃이다. 객체지향 개발과 모든 디자인 패턴의 핵심이 되는 존재이다.

개발자중에 누군가는 인터페이스 덕분에 객체지향 개발 효과를 충분히 얻는다. 또는 인터페이스 때문에 객체지향 개발을 포기한다. 또는 인터페이스를 모른체 객체지향의 탈을 쓴 개발을 한다. 인터페이스는 쉽게 알수도 있지만 쉽게 알기도 어려운 존재이다. 나는 3번째 경우처럼 인터페이스를 이해하지 모른체 객체지향의 탈을 쓴 개발을 하곤 했다. 인터페이스의 실체를 알고 사용하게 됐을때 나는 안도의 한숨을 내쉬었다.


인터페이스는 약속이다. 인터페이스는 나는 너희들에게 이러이러한 기능을 제공하겠다는 약속이다. 다른 모든 객체들은 인터페이스가 약속한 기능들을 믿고 인터페이스에 약속된 기능을 호출한다. 이때 인터페이스에 약속된 기능의 실제 구현은 ‘구상 클래스’ 에서 담당하게 된다. 인터페이스를 호출하는 ‘클라이언트’는 인터페이스에만 의존하고 있지만 실제로 할당된 객체는 ‘구상 클래스’ 이다.
 

[그림 1.2.1-1, 이 그림은 인터페이스를 활용한 전형적인 상속 클래스 다이어그램이다. 클라이언트는 휴대폰 인터페이스에만 의존하며, 휴대폰 인터페이스에서 약속한 기능을 호출한다. 지금 클라이언트는 휴대폰 인터페이스에만 의존하여 있지만 실제로 클라이언트에 할당된 객체는 블랙잭, 아이폰, 햅틱 객체중 하나가 될 것이다.]
 

[그림 1.2.1-2, 실행 클래스는 모든 프로그램이 시작되고 제어되는 부분인 main() 메소드를 포함한 클래스이다. 실행 클래스는 빨간 화살표처럼 프로그램을 구성하는 대부분의 클래스를 알고 있다. 실행 클래스는 클라이언트 객체를 생성할 때, 휴대폰 인터페이스의 기능을 실제로 구현한 클래스 블랙잭, 아이폰, 햅틱중 하나를 인자로 넘겨줄 것이다. ]

- 실행 클래스
public static void main( String[] args ) throws Exception {
    …..
    Clinet client1 = new Client(blackjack); // 1
    …...
}

- 클라이언트 클래스
public class Client {
    Handphone handphone = null; // 2
    public Client(Handphone handphone) {
         this.handphone = handphone; // 3
    }
    …..
}
[1. 실행 클래스에서 Client 객체를 생성하면서 핸드폰 관련 클래스중 어느 구상 클래스를 사용할지 인자로 넘겨준다.
2. Client 객체는 Handphone 인터페이스를 속성으로 가지고 있다.
3. 1.의 절차에 의해 휴대폰 구현 객체 blackjack이 생성자로 넘어왔으며 이 구현 객체가 handphone객체에 저장이 되었다.
이 그림과 코드는 인터페이스, 상속, 다형성 요소가 들어간 객체지향을 이해하는 핵심이 되는 부분이다. 앞으로 계속 설명되니 가능한 부분 까지 이해해도 좋을 것이다.]


내가 처음 겪었던 혼란은 프로그래밍을 해야 할 때, 복잡하게 생각할 필요 없이 하나의 클래스만 만들어 그곳에 기능도 선언하고, 그 기능에 해당하는 로직도 직접 구현하는것이 더 깔끔하게 프로그램 짜는것이 아닐까라고 생각했던 적이 있다. 왜 굳이 인터페이스와 클래스로 나누는가 라고 생각한적이 있다. 당시 나는 ‘클래스의 수만 적으면 깔끔’하다고 생각했던 것 같다.

 

[그림 1.1.3-3, 휴대폰 클래스 하나에 블랙잭, 아이폰, 햅틱, 기타 휴대폰 객체에 의존하고 관련 로직을 꾸역 꾸역 넣으면 어떻게 될까. 저 그림을 코드로 구현하면 얼마나 지저분할지 생각해보자. 코드의 확장성과 유지보수 관점에서 생각해볼만 하다.]

객체지향 개발에서 인터페이스를 쓰면, ‘인터페이스의 기능을 쓰려는 클라이언트’가 인터페이스에 정의된 ‘기능 명세’만 알고 내부는 어떻게 구현되었는지 의식할 필요가 없다는 것을 명확하게 알려주는 효과를 얻을 수 있다.

여러가지 지저분한 로직이 함께 포함된 클래스보다 좀더 ‘직관적’으로 ‘기능 명세’를 클라이언트에게 알려준다. 이점은 구현 클래스의 로직을 숨기는 효과도 있다. 구현 클래스와 구현 클래스의 로직을 숨길 때 얻는 효과는, 구현 클래스를 다른 클라이언트가 필요 이상으로 의존하고 조작하는 점을 막을 수 있다. 그래서 좋은 프로그램을 판단하는 기준인 ‘응집도를 높이고 결합도를 낮추는 효과’가 있다.

구현클래스와 구현 클래스의 로직을 숨기는 효과와 함께 다양한 구현 클래스와 로직을 쉽게 바꾸거나 확장 할 수 있기 때문에 ‘유연함’과 ‘확장성’을 높이는 효과가 있다.

클라이언트가 인터페이스만 알고 구현클래스는 모르는 상태이다. 이때 ‘클라이언트’와 ‘인터페이스’를 조작하는 ‘실행 클래스’가 ‘클라이언트’ 에게 어떤 ‘ 구현 클래스를’ 쓰게 할 것인지 선택할 수 있다.

예를들어 산골이라는 개발자가 객체지향을 공부하기 위해 책을 읽고 있었다. 그런데 개발자 산골이가 객체지향 책 인터페이스를 구현한 클래스에 직접 의존한다면, 개발자 산골이는 직접 의존한 책들만 읽을 수 있다. 개발자 산골이가 자신이 아는 책 말고 다른 책도 읽으려면 자신의 생각을 뜯어 고쳐야 하기 때문에(개발자 산골이 클래스의 내부 소스를 수정해야 하기 때문에), 개발자 산골이보고 다른 책도 읽어보라고 설득하기 어렵다.(기존 클래스의 소스 수정은 어렵고 위험한 적업이다.)

 

[그림 1.1.3-4, 객체지향 지식 습득에 문제가 있는 개발자 산골이]

그러나 객체지향 책 인터페이스 만을 참조한다면 어떤 책을 읽을것인지 프로그램이 실행 될때, 입맛에 맛게 고를 수 있다. 마치 개발자 산골이가 열린 생각으로 여러 책을 읽어보겠다는 긍정적인 마음과 같다.

 

[그림 1.1.3-5, 정상적인 객체지향 책 읽기 구성, 전형적인 인터페이스-상속-다형성을 활용한 클래스 구성이며 Strategy Pattern이기도 하다.]

그림 1.1.3-5처럼 인터페이스(또는 추상 클래스)를 활용하여 상속 객체를 만들고 상속 객체를 다형성을 이용하여 동적으로 객체를 생성하는 구성이야말로 객체지향의 효과를 볼 수 있는 전형적인 구성이다.

 또한 Strateg Patter 이라는 디자인 패턴의 출발이 되며, 스프링 프레임워크의 IoC(Inversion Of Control, 제어 역행)기능에서도 항상 사용되는 클래스 구성이다.

이 클래스 구성의 중심에 인터페이스가 존재한다. 그래서 인터페이스는 객체지향의 정수이고 객체지향의 꽃이다.
 

인터페이스의 다른 특징으론 자바에서 다중 상속이 가능한 효과가 있다. 자바에서 클래스간의 상속은 여러 부모 클래스를 동시에 상속받는것이 금지되어 있다. 그러나 인터페이스를 쓰면 여러 특징을 가진 명세를 동시에 상속/구현하여 설계하려는 특색에 맞는 ‘클래스 패밀리’로 관계를 맺을 수 있다..

내가 처음 객체지향에 대해 배울때는 어려운 공학 이론 배우듯이, 객체란 무엇이고, 클래스란 무엇이고, 속성은 무엇이고, 이런 개념만 암기하려고 했기 때문에 제대로 활용하기가 어려웠다. 그러나 지금에 와서 느낀것은 무엇보다 객체 구성 요소를 골고루 알고 그중에 인터페이스의 정확한 뜻을 알고 그 용도를 이해해야만 객체지향 개발을 제대로 하는 밑거름이 된다는 것이었다.


덧) 아직 고쳐쓰기가 덜 되었습니다. 예를 들면 도입부는 그럴듯하게 쓰다가 실제 설명부분에서는 풀어쓰는 부분이 덜 되었습니다. 어려운 용어의 풀어쓰기가 안되었습니다. 기타 삽화가 부족함을 이해해 주시길 바라며, 향후 책에 쓰일 원천 자료이기 때문에 펌은 불허, 링크 환영 합니다. 조언 부탁드립니다. ^ ^;