brunch

You can make anything
by writing

C.S.Lewis

추상화의 활용

* 이 내용은 철저히 초심자를 위해 알기 쉽게 설명하는 것을 목적으로 하고 있습니다.

* 더 정확하고 자세한 개념은 다른 고수님들의 글들을 참고하시길 바랍니다.

* 그리고 이 글에서는 코드 최소한으로 다루고 있습니다.


앞에서 예고했듯이 이번에는  추상화를 사용하면 코드 상에 어떤 이점이 있는지 확인해 보도록 하겠습니다.

우선 우리는 추상화 활용 시 이점에 대해 알아보기 이전에 결합도 라는 개념을 알 필요가 있습니다.

결합도란 소프트공학에서는 모듈 간의 상호 의존성을 나타내는 정도라고 표현하고 있습니다.


이런 사전적인 내용만 가지고는 정확히 결합도가 무엇인지 파악하기 어렵죠? 그래서 하나씩 천천히 이해해 나가고자 합니다.

우선 결합도(coupling)는 커플이라는 단어가 들어가니 이걸로부터 설명을 풀어나가 보겠습니다.

1일 차 커플보다는 1년 차 커플이 더 끈끈할 것입니다.

그리고 헤어졌을 때 서로의 빈자리가 더 잘 느껴질 것이며, 서로 깨끗이 잊어버리기까지 지워야 할 기억이 너무도 많을 것입니다.

왜냐하면 서로 간에 의존을 많이 해 왔을 테니까요.

그래서 1년 차 커플은 1일 차 커플보다 결합도가 강한 것입니다. 그렇기 때문에 둘을 떼어놓고 다른 짝을 만나는데 보다 많은 고통이 수반됩니다.


이렇게 결합도가 높다는 것은 서로 얽히고설킨 부분이 많기에 분리하는데 많은 비용이 든다.라고 가볍게 생각하시면 좋을 것 같습니다.

그럼 결합도가 낮다는 것은? 

당연히 서로 간의 의존도가 적기 때문에 분리하는데 적은 비용이 든다는 것이 됩니다.

그럼 생활 속에서 결합도가 높은 것과 낮은 것을 찾아볼까요?

결합도가 높은 것은 사람의 신체, 그리고 낮은 것은 로봇이라고 볼 수 있겠네요.

예를 들어 팔 부분이 좋지 않아 교체를 해야 한다고 생각해 보겠습니다.

로봇은 부품을 구해와 갈아 끼우면 됩니다. 그런데 사람은 요? 상상하기 끔찍하니 여기까지만 하겠습니다.


그럼 이건 어떤가요?

둘 중 어느 것이 더 결합도가 높아 보이나요?

아마도 왼쪽으로 생각하시는 분들이 훨씬 많을 것으로 예상됩니다.

오른쪽의 그림은 A와  B를 분리할 때 부러뜨려야 할 것 같아 보이기 때문입니다.

하지만 왼쪽은 분리하기가 한결 쉬워 보이죠?


우리 주변에 보면 이렇게 뚜껑이 분리되는 볼펜이 있습니다.

이것 역시도 결합도가 낮다고 볼 수 있습니다.

얼마든지 분리와 합체가 가능하고, 규격만 맞다면 다른 펜에 바꿔 끼울 수도 있습니다.


규격만 맞다면?

바로 그겁니다.

결합도를 낮추기 위해서는 바로 규격이 필요합니다.

로봇 관절도, 뚜껑이 분리되는 볼펜도 모두 일정한 크기와 끼우고 분리하는 방법에 대해 규격을 가지고 있습니다. 즉 규격이 있으면 결합도를 낮추는데 상당한 도움이 되는 것입니다.


프로그래밍 영역에서 생각해 보겠습니다.

우선 결합도는 낮을수록 좋다는 걸 확인했습니다. 프로그래밍에서도 5분 뒤 알람 맞춰줘. 결합도가 낮으면 프로그램 적으로는 모듈을 추가하거나 교체 또는 제거했을 때 수정할 코드의 양이 적어지기 때문입니다.

이런 결합도를 낮추기 위해서는 규격이 필요하다고 했죠?

이런 규격은 OOP 4대 특성의 추상화를 통해 만들어 낼 수 있었습니다.

즉, 인터페이스나 추상클래스를 통해 규격을 만들어내면 결합도 낮은 프로그램이나 모듈을 개발해 낼 수 있다는 것이죠!


개념적으로는 이해가 되시죠?

하지만 코드적으로는 규격이 어떤 식으로 작용하기에 도움이 되는지는 명확히 떠오르지 않을 것입니다.

그래서 여러분들이 빙수를 만드는 프로그램을 만든다는 가정을 해 보겠습니다.

우선 위의 클래스 다이어그램을 살펴보자면 iceFlake(), milk(), readBean(), jelly()라는 메서드는 각 클래스마다 가지고 있어서 중복 코드가 되겠군요.

그 외에는 빙수마다의 특징을 갖는 메서드를 지니고 있는 형태입니다.


여기에 추가로 30개의 빙수가 추가된다고 생각해 보겠습니다.

일이 굉장히 많아지겠죠? 각 빙수 클래스를 만들 때 중복코드도 많아질 분더러 VingsuMachine에 이것을 객체화하여 실행할 메서드도 늘려줘야 합니다.

이후 얼음을 갈아 넣는 방식이 변경되고 iceFlake() 메서드의 내용을 변경해야 한다면요?

33개의 클래스를 쫓아다니며 iceFlake() 메서드를 수정해야 하는 일이 발생합니다.

그러다가 잘 안 팔리는 빙수를 없애기로 했다면요?

해당 빙수 클래스를 제거함과 동시에 VingsuMacnie 클래스에서는 해당 객체를 사용하는 메서드 들고 함께 제거해 줘야 합니다.

상상만 해도 지치죠?


이번엔 공통되는 코드를 Vingsu라는 추상 클래스에 만듭니다.

그러면 이 클래스를 상속받는 클래스들은 이 코드를 자기 것처럼 쓸 수 있습니다.

그리고 etc()라는 추상 메서드는 각 빙수의 클래스에서 강제 오버라이드 되어 자신의 특색 있는 기능들을 넣을 수 있습니다.

그러면 빙수의 개수가 늘어난다 해도 중복코드 없이 etc() 메서드만 작성하면 됩니다.

그리고 iceFlake() 방식이 바뀌었다면 추상 클래스에서만 바꿔주면 됩니다.

만약 몇몇 빙수에서만 iceFlake() 방식을 변경하고 싶다고 하면 오버라이드 해서 변경하면 그만입니다.

그리고 마지막으로 VingsuMachine에서 빙수를 주문하는 makeVingsu 메서드에서는 Vingsu를 상속받은 객체는 누구나 들어올 수 있도록 매개변수 다형성을 사용했으니, 빙수의 종류가 추가되거나 사라진다 해도 변경할 필요가 없어집니다.


물론 추상 클래스가 아닌 인터페이스로도 충분히 가능합니다.

자바 버전이 1.8 이상이라면 일반 메서드도 만들 수 있기 때문이죠.

참고로 인터페이스도 다형성을 활용할 수 있습니다.

즉, 특정 인터페이스를 구현받은 클래스는 해당 인터페이스 형태로 들어갈 수 있다는 것이죠!


결합도와 이 결합도를 낮추기 위한 추상화의 활용법, 어렵지 않죠?

드디어 OOP 4대 특성을 모두 알아보았습니다.

캡슐화는 사용자가 실수로 주요 소스를 건드려 오작동되는 것을 방지해 주었습니다.

상속은 사용자 입장에서 한 클래스의 객체화를 통해 다른 클래스의 기능들도 쉽게 사용할 수 있게 해 주었습니다.

다형성은 어떤 공통점이 있으면 그 형태로 들어감으로써 객체 사용을 보다 편리하게 할 수 있었죠?

그리고 마지막으로 추상화는 규격을 통해 코드를 더 간결하고 결합도를 낮출 수 있는 방향으로 이끌어주었습니다.

이 네 가지의 특성은 하나만 사용하기도 또는 여러 가지가 조합되어 사용되기도 합니다.

앞으로 배워나가면서 이 특성들은 나올 때마다 계속 언급을 할 것입니다.

그러면서 점점 더 왜 이러한 개념들이 유용한지를 여러분들도 느끼게 되리라 생각합니다.


여기까지 보시면서 대략적으로 라도 고개가 끄덕여졌다면 여러분들은 자바를 공부하면서 가장 많이 포기한다는 클래스의 큰 산을 넘으신 겁니다. 스스로에 대해서 뿌듯해하셔도 좋습니다.

자바에 대해 몇 년을 공부해도 이해가 잘 안 가는 개념들을 이해하신 거니까요.

이 개념들에 대해 이해가 되셨다면 앞으로 공부하게 될 내용들에 대해서 더욱 재미있게 느껴지실 겁니다.

기대하셔도 좋습니다.

매거진의 이전글 인터페이스-2
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari