나의 독학은

객체지향의 사실과 오해 본문

도서/IT 도서

객체지향의 사실과 오해

안종혁 2023. 10. 6. 17:06

'우테코 6기 준비' 오픈채팅방에서 6기 준비생들의 많은 질문들마다 정성스럽게 답변 해주시는 5기 교육생님이 계셨다.

이 분이 6기 준비생들을 위해 '객체지향의 사실과 오해' 와 '함께 자라기' 를 추천 해주셔서 읽게 되었다.

이 기회에 객체 지향이 무엇인지 정립해 보고자 한다.

😁본론

나는 객체지향에 대해 자바의 정석을 배우면서 알게 된 캡슐화, 추상화, 다형성만 알고 있는 상태로 책을 읽었다.

 

책을 읽으며 객체지향 코드의 예시를 생각하며 읽고자 했지만 내가 아는 객체지향 코드의 예시가 있을리가 없었다ㅎㅎ

그래서, 상태와 메시지 파트는 이해하지 못한 채로 1회독을 마쳤다.

객체지향 코드의 예시를 알아보고자 1회독을 끝낸 후 조영호님의 세미나 강연과 김영한님의 스프링 강의 객체지향 파트를 추가적으로 들었고 2회독을 해봤다.

 

❗책의 내용을 이해하기 위해 예시를 떠올리며 이해했던 과정을 적은 글이라서 책의 내용보다는 주로 저의 생각이 나옵니다.

✅[행동과 상태를 통해 캡슐화를 이해하기]

행동이 메서드이고, 상태는 멤버 변수이다. 행동과 상태는 의존적이다.(의존한다는 관련 있다는 말과 동일)

즉, 행동에 의해 객체의 상태가 결정된다 ➡️ 메서드에 의해 멤버 변수의 값이 변경된다.

 

만약 메서드에 의해 멤버변수가 변경되지 않는다면 (행동에 의해 상태가 변경되지 않는다면) 멤버 변수는 상수나 enum을 이용해서 객체에 종속적이지 않도록 설계 한다.

 

그리고, 객체 A는 객체 B의 행동을 볼 수 있지만 행동에 의해 객체 B가 어떤 상태를 가지는지는 모른다.

즉, 메서드는 public하게 멤버 변수는 private 하게 제어자를 설정하여 캡슐화를 시킨다.

✅ [행동에 맞는 상태를 정의해야 한다]

동일한 멤버 변수인 바퀴(wheel)를 가지는 자동차와 오토바이가 있다고 하자.

 

첫 번째는 상태에 따라 행동을 정의할 때이다.

자동차는 4개의 바퀴를 이용하고 오토바이는 2개의 바퀴를 이용해서 움직인다.

즉, 상태에 따라 행동을 정의했더니 movable 메서드가 자동차 객체와 오토바이 객체에 각각 존재할 것이다(movable메서드 중복).

 

두 번째는 행동에 따라 상태를 정의할 때이다.

자동차는 움직이기 위해 4개의 바퀴가 있으면 된다. 오토바이는 2개의 바퀴가 있으면 된다.

즉, 행동에 따라 상태를 정의하면 vehicle 인터페이스에 movable 메서드를 정의하고 자동차 객체와 오토바이 객체는 vehicle 인터페이스를 구현하면 될 것이다.

 

이렇게 설계하는 것이 객체 지향의 목표인 다형성을 만족한다. 그러니 행동을 우선으로 설계하자

✅ [일반화/특수화의 차이]

이해를 돕기 위해 특수화를 구체화로 설명한다.

 

자동차 중에서 엉따와 등따의 기능을 가지고 있는 소나타가 있다고 하자.

질문에 답해보자.

모든 자동차가 소나타의 특징인 엉따와 등따를 가지고 있는가?   그렇지 않다.

모든 소나타가 자동차의 특징인 움직이는 행동이 있는가?     그렇다.

즉, 집합관계로 포현하자면 자동차 ⊃ 소나타 이다.

 

자동차를 구체화 하면 소나타이다. 소나타를 일반화 하면 자동차이다.

결국 소나타는 자동차를 상속받을 것이고, 엉따와 등따의 기능을 하는 메서드만을 추가하면 될 것이다.

구체화 된 객체일 수록 더 많은 메서드가 있다.

✅ [타입]

행동에 따라 타입별로 객체를 분류한다. 타입별로 분류한 객체를 시각적으로 나타내기 위해 쓰이는 도구 중 하나가 클래스이다.

상태와 무관하게 동일하게 행동할 수 있는 객체들은 동일한 타입의 인스턴스로 분류한다.

✅ [협력]

자동차에 얼마나 많은 행동(기능)들이 있는데 다 정의해야 할까?

답은 주어진 상황이나 문맥 속에서 요구되는 행동들만 정의하면 된다.

 

실내 낮 운전연습을 위한 서비스를 만들어 본다면 자동차의 와이퍼 기능과 점조등 기능은 필요없게 된다.

도로를 주행하기 위해 움직이고, 깜빡이를 키고, 악셀과 브레이크를 밟는 행동들만 있으면 된다.

 

즉, 주어진 상황에 맞는 객체의 행동을 정의하는 것이 객체가 서비스를 위해 협력할 수 있는 첫 걸음이다.

✅ [책임]

실내 낮 운전연습이란 서비스에 협력하기 위해 vehicle이 필요하다. vehicle은 movable할 책임을 갖고 있어야 하고, 이 책임에 알맞는 역할이 자동차 객체이다. 그렇게 movable할 책임을 자동차란 객체를 만들어 자동차에 구현한다.

 

책임은 '어떻게 해야 하는가' 가 아니라 '무엇을 해야 하는가'를 기준으로 부여해야 한다.

잘못된 예 - 자동차는 움직일 때 4개의 바퀴를 이용한다.

옳은 예 - 자동차는 움직여야 한다.

 

자동차를 오토바이로 바꿔만 보아도 어떤 것이 옳은 지를 알 수가 있다.

✅ [동일한 책임은 역할, 대체 가능성이 있는 것을 보여준다]

실내 운전연습을 오토바이로 하고 싶다. 자동차를 오토바이로 바꾸기만 하면 된다.

오토바이도 움직일 책임을 수행할 수 있기 때문이다.

 

즉, 동일한 책임을 수행할 수 있는 객체로 대체할 수 있는 것은 객체 지향의 유연성, 재사용성을 보여준다.

✅ [동일한 책임을 수행하여 대체 가능한 것은 다형성이다]

실내 운전 연습장 서비스의 'movable' 이라는 메시지와 책임을 수행할 역할은 자동차, 트럭, 오토바이 등 다양하다.

자동차, 트럭, 오토바이는 'movable' 이라는 메시지를 처리하는 방법은 각자 다르지만, 메시지를 처리할 수 있는 공통점이 있다. 이는 자동차, 트럭, 오토바이는 서로 대체가능성을 의미하고 이를 다형성이라 한다.

✅ [구현 도중에 설계는 바뀔 수 있다]

설계는 코드로 구현하는 과정에서 대부분 변경된다. 그러니 협력을 구상하는 단계에서 많은 시간을 쏟지 말고 최대한 빨리 코드로 구현해서 설계에 이상이 없는지, 설계가 구현 가능한지를 파악해야 한다.

✅ [패키지]

패키지는 내부에 포함된 클래스들을 감춤으로써 시스템의 구조를 추상화한다.

시스템을 바라볼 때, 같은 행위를 하는 클래스들을 하나의 패키지에 넣음으로써 패키지만 보더라도 협력의 방향을 알 수 있게 해주기.

✅ [메시지]

"왕은 모자장수에게 증언하라" 라는 메시지가 있다. 이를 코드로 나타내면 King 객체 안에는 ManOnHat.testify(); 가 있겠다. 그러면 모자장수는 증언할 책임이 있고, 증언할 책임은 곧 모자장수 객체가 testify 란 메서드가 가지게 한다.

→ void testify(){...} 란 메소드의 구현 방식은 모자장수 마음이다!

만약, 왕이 모자장수에게 "어디서, 무엇을" 을 포함해서 증언하라와 같이 추가적인 정보를 요구한다면 요구하는 정보들을 인자에 넣어 메시지를 완성하면 된다. → void testify(place, what)

 

메시지를 결정하기 전까지는 객체에 관해 고민하지 말기~!

😁 후기

책을 읽기 전에는 정말 객체지향에 대해 무지했다고 자부할 수 있었지만, 객체지향을 바라보는 태도 및 접근법에 대해 확실하게 알게 되었다.

1회독은 정말 추상적인 책을 보는 것과 같이 두루뭉술하게 이해한다는 느낌이 들었다.

그러나, 2회독은 예시를 생각하며 읽게 되어 책이 말하고자 하는 바를 이해하게 되었다!

객체지향의 입문서로 다들 추천하는 이유가 있다🤝

 

객체지향의 사실과 오해

 

'도서 > IT 도서' 카테고리의 다른 글

'함께 자라기'를 읽고  (2) 2023.09.06