본문 바로가기
IT 기술 서적/후기

⌜객체지향의 사실과 오해⌟로 배운 진짜 OOP

by 그냥노깡 2022. 6. 28.

(책 내용을 배제하고 느낀 점 위주로 작성하려고 노력했습니다.

그럼에도 블로그 내용이 문제될 시 연락 주시면 바로 삭제 조치하겠습니다.)

연락처: rkdgh98@khu.ac.kr

 

https://book.naver.com/bookdb/book_detail.nhn?bid=9145968 

 

객체지향의 사실과 오해

객체지향에 대한 선입견을 버려라!『객체지향의 사실과 오해』는 객체지향이란 무엇인가라는 원론적면서도 다소 위험한 질문에 답하기 위해 쓰여진 책이다. 안타깝게도 많은 사람들이 객체지

book.naver.com

 

책을 읽게 된 계기

대학에 입학하고, 신입생 때 '객체지향 프로그래밍'이라는 이름의 수업을 수강한 적이 있다.

수강 당시에는 시험 성적에만 치중된 공부 방법으로 공부했었다.

추상화, 캡슐화, 다형성, 상속 등에 대한 지루한 이론적 개념을 달달 외우거나,

라이브 코딩으로 오버로딩, 오버라이딩의 차이점을 단순하게 실습만 하고 넘어가거나,

시험에서는 단순한 추상 클래스와 상속 관계의 여러 클래스들을 구현 해보는 게 전부였다.

 

좋은 성적을 받았을지언정,

결국 나에게 남은 것은 '객체지향은 복잡하다' 라는 생각이었다.

이렇게나 많은 개념들을 추가적으로 공부해야 하는데,

어떤 부분에서 '왜' 효율적인 것인지도 제대로 이해하지 못하는 상태였다.

 

(학교 수업이 잘못되었다는 말은 아니다.

아마 강의의 제목이 객체지향 '설계'가 아닌 객체지향 '프로그래밍' 이었기 때문에

한정된 시간 안에 학생들을 가르치기 위해서

수업 내용이 '객체들의 협력에 집중한 설계'에 대한 강조보다는,

'클래스를 구현하는 방법'에 치중된 게 아닌가 생각한다.)

 

이제 4학년이 되었고, Java Spring을 사용하는 백엔드 개발자의 꿈을 키우면서,

과연 내가 정말로 객체지향 언어인 Java의 장점을 잘 살리면서 코드를 짜고 있는가에 대한 의문이 생기기 시작했다.

 

팀 프로젝트 두세 개를 진행하다보니

단지 객체지향 언어에 있는 기능들을 코드로 짤 줄 아는 정도의 수준이지,

제대로 객체지향을 활용하고 있지 못하고 있다는 것을 깨닫게 되었다.

인터페이스와 구현을 제대로 분리시키지 못한다거나, 하나의 객체가 여러 개의 책임을 떠맡는 등

객체지향의 장점을 하나도 살리지 못하고 있었다. 객체지향을 다시 처음부터 공부해야 겠다고 생각했다.

 

그렇기 때문에 이 책을 꼭 읽어야겠다고 생각했다.

객체지향에 대한 올바른 이해와 사용을 위해서

내가 도전했던 우아한 프리코스 과정에서 이 책을 읽으라는 피드백을 받았었고,

지금 인프런에서 듣고 있는 Spring 강의의 김영한 님께서도 객체지향을 설명하면서 강력 추천한 책이었기 때문이다.

 

결론부터 말하면 책을 다 읽은 지금,

앞으로 어떻게 객체지향 설계를 하고 코드를 짜야 할지 확실한 기준과 방향을 세울 수 있게 된 것 같아 굉장히 만족스럽다.

책을 읽은 후 김영한님의 '스프링 핵심원리 - 기본편' 강의를 2회차로 들었는데, 이해의 깊이 차이를 체감하기도 했다.

 

여기서 안주하지 않고 더 깊은 이해를 위해

블로그 글로 각 장 별 깨달은 내용들을 정리해보고,

예전에 진행했던 프로젝트 코드를 더 깔끔하게 리팩토링해보려고 한다.

 


각 장 별 느낀 점, 깨달은 점

 

1장: 협력하는 객체들의 공동체

객체지향에서 중요한 것은 클래스나 상속이 아니다.
핵심은 적절한 '책임'을 수행하는 '역할' 간의 유연하고 견고한 '협력' 관계를 구축하는 것이다.

 

 

 첫 장은 잘못 알려진 객체지향의 진짜 의미를 설명하는 장이다.

'클래스에 집중하지 말고 객체의 역할과 책임, 객체 간의 협력 관계, 그리고 객체의 자율성에 집중하라' 라는 이 책 전체를 관통하는 메시지를 담은 장이었다.

 

이 장을 읽으면서 프로젝트를 할 때 나의 프로그래밍 과정이 완전히 잘못된 방식이었다는 것을 깨달았다.

나는 줄곧 클래스를 먼저 생각해왔다. 클래스부터 만들고 그 다음 생각했다. 그렇게 코딩하다보니 이후에는 그 틀 안에서만 뭔갈 추가해야 했고, 나중 가서 문제가 발생하면 점점 더 더러운 스파게티 코드가 되곤 했다. 나의 객체지향 코딩 방식이 완전히 처음부터 잘못되었다는 것을 깨달은 장이었다.

 

 

2장: 이상한 나라의 객체

은유를 효과적으로 사용할 때, 이해하기 쉽고 유지보수가 편리한 소프트웨어를 만들 수 있다.

 

'이상한 나라의 앨리스' 동화를 객체에 은유하여 설명하는 장이다.

이를 통해 객체가 가진 특성을 설명하고, 객체지향이 현실세계의 '모방'이 아니라 현실세계를 기반으로 새로운 세계를 창조하는 '은유'에 가깝다는 것을 강조한다.

 

'모방'과 '은유'는 확실히 다르다는 것을 알 수 있던 장이다. 객체의 '상태', '행동', '식별자'를 통해 현실세계의 복잡한 부분들을 단순화하여 표현하고, 마치 이상한 나라의 앨리스의 트럼프 카드가 실세계의 트럼프 카드와는 달리 자율성을 가지고 스스로 움직이는 것처럼 은유하여 창조해내는 것이 객체지향이다. 그것이 바로 객체이고, 이 객체들 간의 협력으로 소프트웨어가 돌아간다. 이런 형태로 구현해야 유연한 소프트웨어를 만들 수 있다.

 

 

3장:  타입과 추상화

타입은 추상화다.
타입은 시간에 따른 객체의 상태 변경이라는 복잡성을 단순화(추상화)할 수 있는 효과적인 방법이다.

 

프로그램의 동작은 사람이 이해하기에 복잡성을 가지고 있다. 프로그램은 시간에 따라 변화하는 수많은 객체들의 협력과정이기 때문이다.

 

우리가 디버깅 툴을 사용해서 디버깅을 하는 이유와 비슷한 것 같다.

디버깅 툴은 동적인 프로그램을 개발자가 원하는 순간순간 마다 멈춰서 정적인 스냅샷으로 그 때 프로그램의 상태를 프로그래머에게 제공해준다.

만약 디버깅 툴이 없다면? 눈으로 코드를 읽으면서 그 때 그 때 상태를 기억하면서 진행해야 한다. 이 방법은 사람이 직접하기에 뇌의 과부하가 심하게 올 것이다.

 

이와 같이 프로그램 실행 시점에서 객체들의 복잡성을 단순화할 수 있는 것이 정적으로 표현할 수 있는 타입이고,

타입을 구현하는 방법 중 한 가지가 우리가 익히 알고 있는 클래스라는 내용을 담은 장이다.

 

4장: 역할, 책임, 협력

객체지향 설계의 전체적인 품질을 결정하는 것은 '협력의 품질'이다.
어떤 협력에 참여하는지가 객체에 필요한 행동을 결정하고,
필요한 행동이 객체의 상태를 결정한다.

항상 클래스부터 작성했던 나의 코딩 방식을 어떻게 바꿔야 할 지 제시해주는 장이다.

프로그램은 객체들의 협력이다. 객체들을 독립적으로 바라봐선 안되고, 협력이라는 문맥을 고려해야 한다.

문맥 속에서 수행해야 할 행동(책임)을 발견하고, 책임을 어떤 객체에 부여할지 고민하자. 또, 그 객체가 필요하지만 알지 못하는 정보는 다른 객체에 요청하도록 설계하여 두 객체가 협력하도록 만들자.

 

5장: 책임과 메시지

메시지를 믿어라. 그러면 자율적인 책임은 저절로 따라올 것이다.

 

객체지향의 5원칙 중 OCP, DIP와 가장 맞닿아 있는 장이라고 생각한다. 객체지향의 특성 중, 다형성을 지키기 위해서는 '인터페이스와 구현'을 분리해야 한다. 이 장에서는 메시지와 메서드를 분리하여, '무엇'을 수행할지는 명확하게 메시지로 표현하고, '어떻게' 수행할지는 객체 내부에서 자율적으로 표현하라고 강조한다. 내부 구현의 변화가 외부에 영향을 주지 않도록 만드는 것이다. 객체의 자율성은 소프트웨어를 더 유연하고 확장 가능하게 만든다.

 

6장: 객체 지도

성공적인 소프트웨어들이 지닌 공통적인 특징은
훌륭한 기능을 제공하는 동시에,
사용자가 원하는 새로운 기능을 빠르고 안정적으로 추가할 수 있다는 것이다.

 

현재 나에게 가장 필요한 경험이 무엇인가 스스로 물어본다면, '유지보수 경험'이라고 생각한다.

지금까지 내가 수행해온 프로젝트들은 실제 운영된 적이 없어서

요구사항이 변경되거나 오류가 발견되어서 유지보수를 진행한 프로젝트가 거의 없다.

 

하지만 이후에 내가 취업하고 나면,

실무에서는 이미 있는 프로그램에 새로운 기능을 추가하는 것은 물론이고,

요구사항의 변경으로 인한 유지보수하는 시간이 개발하는 시간보다 더 많을 것이다.

그리고 코드를 통해 여러 부서와 소통하게 될 것이다. 서로의 코드를 이해하기 위한 시간도 단축된다면 더 좋을 것이다.

 

그렇기 때문에 유지보수가 쉽도록 처음부터 객체지향적으로 프로그램을 설계하는 능력과 누구나 이해 가능한 코드를 구현할 수 있는 능력은 필수적이다.

내가 이 책을 읽게된 이유도 이것이다.

그런 부분에서 이 장의 의미가 특히 깊었다.

 

이 장은 도메인 모델, 유스케이스, 그리고 책임-주도 설계(RDD)에 대한 개념을 담고 있다.

모든 사람들이 동일한 용어와 동일한 개념을 통해 의사소통하고, 코드로부터 도메인 모델을 유추할 수 있게 하는 도메인 모델과 그 도메인 모델을 기반으로 시스템의 기능을 구현하라고 강조한다.

 

 

7장: 함께 모으기

 앞 장들에서 설명한 내용들을 코드와 다이어그램을 통해 실제 설계와 구현을 보여주는 장이다.

 

간단하게 한 줄로 요약하면,

간단한 도메인 관계를 정의하고, 어떤 유스케이스를 해결하기 위한 메시지들을 정하여 객체들의 책임을 부여하고 서로 간의 협력을 구성하는 방식으로 진행된다. 이후 이러한 설계를 직접 구현하기 위한 도구로 클래스, 인터페이스 등을 사용한다.

 

이렇게 작성된 코드는 객체지향 설계의 목표인 이해하기 쉽고, 유연하지만 견고하며, 유지보수가 뛰어난 소프트웨어가 개발될 수 있다.

 

사실 아직 글로만 읽어서는 완벽하지 않아서, 이후에 내가 예전에 했던 프로젝트 코드들을 리팩토링하거나, 새로운 프로젝트에 적용해보면서 경험을 통해 체득해야겠다.

 


마무리

만약 본인이 학교나 학원에서 배운 객체지향이 '클래스 구현'에 치중된 수업이었다면,

객체지향언어를 공부하고 있지만 스스로 객체지향의 장점을 살리지 못하고 있는 것 같다면,

이 책을 읽기를 강력 추천한다.

객체지향 패러다임을 통해 유연하고 변경에 용이하며, 재사용성이 뛰어난 코드를 개발하는 개발자로서 새로운 눈을 뜨기에 최고의 책이라고 생각한다.

 

 

(책 내용을 배제하고 느낀 점 위주로 작성하려고 노력했습니다.

그럼에도 블로그 내용이 문제될 시 연락 주시면 바로 삭제 조치하겠습니다.)

연락처: rkdgh98@khu.ac.kr