[도서리뷰] 객체지향의 사실과 오해
목차
도서 정보
배경
신입 개발자 또는 개발자를 준비하는 사람들에게 필독 도서라고 느껴질 정도로 워낙 유명하고 기초적인 도서임에도 불구하고 최근에서야 읽기 시작했다. 최근 회사에서 리팩토링 업무를 맡게 되었는데 객체지향의 특성을 살려서 해보는게 어떻냐는 의견을 받았고, 나도 기왕이면 OOP로 설계와 구현을 해보면 좋은 경험이 될 것 같다는 생각이 들어 업무 자체에 흥미도 생겼다.
물론 좋은 경험을 쌓고 업무에 대한 흥미가 생기는건 긍정적인 시그널이다. 하지만 나는 관련지식이 대학교 2학년 전공 수업이후로는 거의 없는 편이였고 이는 실무에 적용하기에는 너무나 기본적인 이론이였기 때문에, 부리나케 실무에 적용하기 위한 지식을 쌓기 위해 관련 도서들을 사서 읽고 공부하기 시작했다.
내용들을 목차별로 간략하게 포스팅을 할 수도 있지만 다시 도서 내용을 다시 되짚어보고자 책 한권을 다 읽고나서 그에 대한 후기를 적어보았다. 책이 소개하는 내용이 많거나 난이도가 있는 편은 아니였지만 정독하면서 읽었고, 챕터를 넘길때마다 그 챕터의 주 내용과 실제로는 어떻게 적용할 수 있을지 등을 머릿속으로 정리해보면서 읽느라 굉장히 오랜시간이 걸렸다. (책 읽는 속도가 워낙 느리기도 하고..)
내용
제목에서 알 수 있듯이 이 책은 객체지향에 대한 개발자들의 흔한 오해와 실제 사실을 서술하는 방식으로 전개된다. 이때 서술 방식은 동화 이상한 나라의 앨리스로부터 모티브를 가져왔다. 간략하게 내용을 더듬어보면 가장 기본적인 개념으로 객체는 상태와 행위라는 두가지 특성을 갖는데, 동화 이상한 나라의 앨리스에서 앨리스가 버섯을 먹고 몸 크기가 변한다면, 앨리스의 상태는 몸 크기이고 행위는 버섯을 먹는다 이다. 이때 객체지향 설계를 위해서는 상태(= 몸 크기) 가 아니라 행위(= 버섯을 먹는다)를 먼저 고민해야한다고 설명했다. 이어서 나오는 내용으로는 행위를 먼저 생각하다보면 적절한 책임을 갖는 객체를 찾게되고(책에서는 '메시지(=행위)가 객체를 찾아간다' 라고 표현했다.), 이는 결국 SOLID, 인터페이스와 구현의 분리, 캡슐화 등 객체지향의 특성을 살리는 구현과 개발로 이어진다는 것이였다.
당장 나만하더라도 처음 객체지향 설계를 해보라는 의견을 들었을때 '객체 지향이라고 하면 클래스가 어떤 필드를 갖는지 먼저 고민하고, 이에 따라 인터페이스 & 구현 & 상속 등.. 을 하면 그게 객체 지향인가?' 라는 생각을 했었는데, 이러한 나의 생각에 대해 책 도입부를 읽자마자 아주 잘못된 오해라는 것을 깨달았다.
또한 두번재 오해로는 객체지향은 현실 세계를 소프트웨어로 옮긴 것이라는 생각이다.
이 말에 대해 책에서는 객체지향은 현실세상의 은유인 것은 맞다. 하지만 그대로 옮긴것은 아니다 라고 설명해주었고, 그러한 이유는 객체 지향 세계의 객체는 자율성을 갖기 때문이라고 소개했다.
현실세계에서 커피잔을 상상해봤을때, 이를 객체지향 세계로 가져오면 커피잔 이라는 객체에 대해 안에 들어있는 커피의 양(상태), 사람이 커피를 마신다(행위)가 있다고 생각할 수 있을 것이다. 하지만 여기서 현실세계와 객체지향 세계의 가장 큰 차이는 현실 세계에서는 누군가가 커피를 마셔야만이 커피잔 안의 액체의 양이 줄어드겠지만, 객체지향 세계에서는 커피잔 스스로 커피를 마신다 라는 행위를 통해 커피의 양을 줄일 수 있다(= 상태를 변경할 수 있다). 이를 클래스로 나타내면 다음과 같을 것이다.
(세번째 오해이기도한데, 이를 클래스로 나타낸 것은 어디까지나 내용 이해를 하기 위함이고 객체가 항상 클래스인것은 아니다.)
public class CoffeeCup {
private int amountOfCoffee; // 커피의 양
public void drinkCoffee(int drink){
amountOfCoffee = drink
}
}
세번째 오해는 앞서 말했듯이, 객체 지향이 항상 클래스라는 생각이다. 이 또한 나 역시 객체지향 설계라고 하면 클래스기반 설계라고 생각했지만, 클래스는 객체를 표현하기 위한 방법 중 하나일 뿐이지 객체지향이라고 해서 전부 클래스는 아니라고 설명해주었다.
이 둘이 동일한 표현이 아닌 이유는, 객체지향세계는 동적이다(앞서 말했듯이 객체는 자율성을 갖고 스스로 메시지(=행위)를 통해 상호작용한다.) 하지만 클래스는 코드상으로 나타낸 정적인 텍스트일 뿐이다.
다시말해, 동적인 객체지향 세계를 이해할 수 있도록 정적인 텍스트로 표현한 방법 중 하나가 클래스인 것이지 객체지향이 항상 클래스 기반 구현을 의미하는 것은 아니라는 오해였다.
화면 개발을 위한 프레임워크 React는 다음과 같이 화면 랜더링을 위한 객체를 만드는데, 이때 amountOfCoffee가 객체의 상태 / setAmountOfCoffee가 객체의 행위라고 생각하면 객체지향은 항상 클래스기반 구현이라는 오해에 벗어나면서 객체지향에 대한 이해를 좀 더 수월하게 할 수 있지 않을까 생각했다.
const [amountOfCoffe, setAmountOfCoffee] = useState<number>(0)
위 코드 또한 setAmountOfCoffee 메소드(객체의 행위)를 통해서 amountOfCoffee라는 객체의 상태를 변경해주어야만 화면에 변경이 생겼다고 인식을 할 수 있다. (어디까지나 저의 의견이고, 혹시나 이해나 예시가 적절하지 못했다면 가감없이 코멘트 주시면 감사하겠습니다 🙂)
사실 가장 선명하게 떠오르는 내용으로는 객체지향으로 설계와 구현을 해야하는 이유이다. 책에서는 후반부에 소개를 하는데, 과거에는 객체지향의 목적을 대충만 알고있었으나, 그 챕터를 읽으면서 명확히 이해할 수 있었다. 기억을 더듬어보자면 어떠한 기능에 대해 변경사항 혹은 요구사항이 생겼을때 객체지향은 구조 기반으로 문제를 해결하고, 대조되는 개념으로는 기능 기반으로 문제를 해결하는 것이였다.
기능 기반으로 문제를 해결하게되면 그 순간은 간단하고 쉽게 문제를 해결할 수 있다. 그 하나의 문제 상황만 해결을 하면 되기 때문이다. 하지만 이는 결국 단순 기능 해결을 위한 수많은 로직이 얽혀 복잡한 로직을 낳게될 것이다. 그리고 매번 소프트웨어의 기능 변경이 이루어질텐데 이 때 마다 모든 영향범위를 파악하는것은 매우 힘든 작업이고, 그 문제를 해결하기 위한 코드 몇줄을 작성하는것은 끔직한 결과를 초래할 것이다. 그렇다고 어떤 변경사항이 올지 예측해서 작업하는건 불가능하다.(권장하지 않는 방법이기도 하다, 소프트웨어 개발 원칙 : YAGNI)
따라서, 매번 발생하는 기능 변경사항에 대해 영향 범위를 최소화하여 유지보수를 용이하기 위한 구조 설계 방법이 객체지향 설계인 것이였다. 객체지향 설계를 통해 개발한다면(이 원칙을 지키기 위한 방법은 책 앞부분에 순차적으로 자세하게 설명이 되어있다.) 자연스레 변경에 안정적인 구조를 설계할 수 있고 이것이 객체지향의 목적이 되는 것이다.
이와 함께 객체지향을 위한 방법인 유스케이스 다이어그램과 클래스 다이어그램 작성 방법 또한 짧게 설명해주었는데, 과거에는 누군가가 다이어그램을 그려보라고하면 어떻게 그러야하나, 어디서부터 시작해야하나 막막했지만 이 책을 통해 감을 잡을 수 있었다. 그리고 다이어그램 작성하면서 실무에서 적용할 수 있는 일종의 팁도 얻을 수 있어서 더 유익했던 것 같다.
객체지향 설계를 하기 위해서는 두가지 다이어그램이 필요한데, 먼저 유스케이스를 그리면서 사용자 중점의 기능들을 생각해보고(책에서는 이를 사용자모델(소프트웨어에 대한 사용자 관점의 도메인 모델) 이라고 설명했다) 그 후에 기능들을 기반으로 클래스 다이어그램을 그려보라고 설명했다. 유스케이스 다이어그램 같은 경우는 기능을 파악하기 위한 목적이므로 다어어그램을 그리는 것에 집중하지말고 어떤 기능들이 있는지 나열하고 정리하는 것에 중점을 두라고 했던 것으로 기억한다.
물론 아무리 세세하게 이러한 다이어그램을 그리는 단계를 거친다고 하더라도, 실제 구현 시에는 변경사항이 생길 수 밖에 없다고 하였다. 따라서 실제로 이러한 다이어그램을 그리면서 소프트웨어 설계를 시작해본다면 너무 많은 시간을 쏟지말고 어느정도 완성되었을때 개발에 진입하라고 하였다. 이와함께 다이어그램을 그리기전에 도메인에 대해 너무 익숙해서 머릿속에서 클래스 설계가 그려진다면, 다이어그램 작성과정없이 바로 구현에 진입해도 좋다고 덧붙였다.(물론 그만큼 객체지향에 대해 충분한 이해와 경험이 있고, 충분히 숙련되었다고 느낄때 그렇게 하는것이 좋을 것이라는 의미로 받아들였다)
너무 인상깊에 읽었던 책이고 하고싶은 말이 많지만, 글이 길어질 것 같아 내용에 대해서는 이정도만 작성하고 후기로 넘어가려고 한다.
후기
책 자체는 그리 어렵지 않았다. 오히려 개발도서치고 친절한 편이였던 것 같다.
책에서 소개해주는 내용을 이해하기위해 곱씹어 보면, 그리고 실무에는 어떻게 적용할 수 있을까 고민하다보면 결국 똑같은 말을 유사한 방식으로 반복한다는 생각이 들었다. 사실과 오해를 단순히 서술하는 것만으로도 큰 도움이 되었을 거라고 생각하는데, 책에서는 이와 함께 후반에는 왜 객체지향으로 설계를 해야하는가?, 실무에서 객체지향으로 설계한다면 어떻게 해야하는가? 등에 대한 내용도 함께 설명이 되어있어서 객체지향의 등장 배경과 목적을 이해하는데 큰 도움이 되었다.
지금 다시 책의 내용을 되짚어봤을때, 초보자가 읽기에도 굉장히 친절하고 좋은 책이라고 생각하고 객체지향에 대한 개념을 제대로 잡을 수 있는 책인 것 같다는 생각이 든다. 만약 이 글을 읽고 관심이 생겼다면 너무 감사한 마음으로 꼭 읽어보기를 권한다.