객체지향의 사실과 오해를 읽고

ds_chanin

·

2019. 12. 4. 00:38


들어가며

학교의 커리큘럼은 C를 배우고 Java를 배우는 순서였습니다.

C는 절차지향 언어이고, Java는 객체지향 언어이다.

전혀 이해가 되질 않았습니다. 전혀. 솔직히 지금도 객체 지향에 대해 설명하라고 하면 자신있게 못 할 것 같습니다.

Java는 코드의 재사용이 가능하다고 하지만 'C도 메서드 재사용 되지않나?'라는 생각을 했습니다.

Java는 그저 알고리즘을 풀기위한 언어 중 한 가지일 뿐이었습니다.

 

그러다 우연히 대외활동을 하다 다른 친구가 Java를 다루는 것을 보았는데 충격적이었습니다.

'와! 내가 작성한 코드는 쓰레기구나!'

제가 작성한 코드는 재활용이 불가능한 코드지만, 친구가 작성한 코드는 재활용도 가능하고 정말 깔끔했습니다.

저는 객체 지향언어를 사용하면서 원칙을 지키지 않았고 친구는 원칙을 지키고 있었습니다.

그리고 친구에게 이 책을 추천받았습니다.

 

이 책의 내용을 Java를 학습한 다음 읽었다면 조금은 코드를 잘 작성하지 않았을까? 라는 생각을 합니다.

책을 여러번 읽었음에도 모든 내용을 이해하지 못했습니다. 다행히 여러번 읽어서 조금은 정리할 점이 생겨 다행입니다.

모든 내용을 정리하고 싶은 마음이 굴뚝같지만 내용이 어렵고 제가 함부로 정리하기에도 힘든 주제라고 생각합니다.

 

그래서 책을 읽으면서

 

  • 앞으로 최소한 지켜서 의식해야겠다 느낀점
  • 제일 좋다고 느낀점

위 두가지를 위주로 '이렇게 하면 조금은 객체 지향에 다가가는 것인가!' 하고 배운 부분에 대해 정리하고자 합니다.

 

역할, 책임, 협력

세 단어를 모두 써서 이 내용을 표현하면

'각자의 역할을 가진 객체가 협력을 위해 책임을 다한다.' 인 것 같습니다.

상당히 추상적인 내용이라 처음에 잘 이해가 가지 않았지만,

 

  1. 객체는 다른 객체와 같이 요구사항을 만족시켜야하는 협력관계에 놓여있다.
  2. 각 객체는 요구사항을 만족하기 위한 책임(기능)을 해야 한다.

라고 저는 정리 할 수 있을것 같습니다.

 

마치 '신호등이 빨간 불이면 멈춰야 한다.' 처럼 당연한 얘기로 들릴 수 있을 것 같습니다.

하지만 진짜 객체가 역할을 가지고 책임을 다하게 하는 것은 정말 어려운 것이라 생각합니다.

저의 경우에 당연하다고 생각하지만 당장 제가 작성했던 코드를 본다면 그렇지 않은 코드들이 대부분이었기 때문입니다.

 

책은 이어서 객체의 책임을 어떻게 부여하는지에 대해 설명해 주었습니다.

 

상태와 행동

이 책은 객체는 상태와 행동을 함께 지닌 실체라고 정의합니다.

상태는 객체의 멤버변수를, 행동은 객체의 메서드를 의미한다고 보면 될 것 같습니다.

항상 클래스를 만들면 가장 먼저하는 행동은 멤버변수(상태)를 작성하는 일이었습니다.

그리고 미리 정해진 멤버변수를 가지고 필요한 메소드(행동)을 작성했습니다.

책은 그렇게 하지말고 반대로 해야한다고 말해줍니다.

행동이 상태를 결정한다.

객체지향에 갓 입문한 사람들이 가장 쉽게 빠지는 함정은 상태를 중심으로 객체를 바라보는 것이다.

상태를 초점으로 맞춘 객체의 설계는 객체를 고립된 상태로 만들게 될 확률이 굉장히 높습니다.

협력은 서로의 행동이 합을 이뤄 행해지는 것이지 상태가 합을 이루는 것이 아니기 때문입니다.

그래서 멤버변수(상태)를 먼저 정의하고 메서드(책임)을 작성하면

다른 객체와의 협력에 초점이 맞춰지지 않게되고 자연스럽게 재사용성이 떨어지는 객체가 생성됩니다.

 

따라서 객체를 설계할 때 데이터 -> 행동 순으로 설계하는 것이 아닌 행동 -> 데이터 순으로 설계를 해야합니다.

 

What-Who 사이클

위와 같이 책임을 우선으로 하여 설계하는 방식을 책임 주도 설계라 하는데

이러한 책임 주도 설계의 과정을 What-Who 사이클이라 부릅니다.

 

이는 단어의 뜻 그대로 협력 관계를 설계할 때

 

  1. 어떤 행위(what)이 필요한지
  2. 누가(who) 그 행위를 할지

정하는 것을 말합니다.

아시다시피 어떤 행위라 함은 책임을 의미하고 누구는 객체를 의미합니다.

 

다시말해 객체를 먼저 설계하고 책임을 부여하는 것이 아닌

요구사항을 분석하여 요구사항을 해결하기 위해(협력을 하기위해) 필요한 책임을 먼저 찾은 후

그 책임을 부여할 객체를 생성하라는 말이었습니다.

 

한번 더 순서를 정해 정리하면 다음과 같을것 같습니다.

 

  1. 협력에 대한 정의
  2. 협력을 수행하기 위한 책임을 정의
  3. 책임을 수행할 객체를 정의

 

맺으며

위와 같은 원칙을 지키며 코드를 작성 하는것은 정말 어렵다고 생각합니다.

따라서 연습이 필요했는데, 저의 경우 다음과 같은 방법으로 연습을 했습니다.

 

첫번째는 알고리즘 문제입니다.

학생인 저의 경우에 위와같은 내용을 접목시킬만한 부분이 많지 않았기에

기존에 해결했던 알고리즘 문제중 시뮬레이션에 해당하는 문제들을 다시 풀어보았습니다.

명확한 요구사항이 있었고 객체들의 협력을 표현하기에 좋은 예제들이 많이 있다고 생각합니다.

 

두번째는 TDD 연습입니다.

책에서도 TDD에 대한 얘기가 잠깐 나오지만 제가 따로 포스팅에서 언급은 하지 않았습니다.

테스트 코드를 작성하는 사이클은 협력을 파악하고 책임을 정의하는 과정이 가장 선행하도록 되어있기때문에

TDD 방식으로 코드를 작성하는 연습 또한 큰 도움이 되는 것 같습니다.

 

세번 읽었지만 읽을 때 마다 새로운 점을 깨닫게 되는 신기하고 좋은 책입니다.

다음에는 이 책에서 새롭게 배운점을 이해하고 정리해서 적을 수 있으면 좋겠습니다.