우아한테크코스 레벨1 백엔드 필독서,
객체지향의 사실과 오해를 읽고 이해한 내용을 저의 언어로 표현해보는 포스팅입니다.
객체지향 프로그래밍
현실 세계 은유로 구조화된 도메인 모델을 자율적 객체들의 협력으로 재창조해내는 것
프로그램을 명령어의 집합이 아니라, 협력하는 객체들의 모임으로 보는 프로그래밍 기법입니다.
사람의 인지 능력에는 한계가 있습니다.
프로그램이 거대해지고 요구사항이 많아질 수록, 내부복잡도는 높아질 수밖에 없고,
이를 개발자가 모두 명령어로 제어하려면 한계가 발생합니다.
이 지점에서 객체들의 책임, 역할, 협력 이라는 개념이 부상합니다.
책임
한 객체가 어떤 메시지를 받을 수 있다면, 그 객체는 그 메시지를 수행할 책임이 있다.
A라는 객체에게 doSomething라는 메시지를 보낼 수 있다면,
A는 doSomething의 책임을 가지고 있다고 말할 수 있습니다.
가령, 요리사에게 "증언하라" 라는 메시지를 보낼 수 있다면,
요리사는 증언하는 책임을 가지고 있다고 말할 수 있습니다.
(ex String testimony = 요리사.confess())
책임을 가진다는 의미는 곧,
그 책임을 완수하기 위해 필요한 지식과 행동을 모두 가지고 있다는 의미이기도 합니다.
그러나 같은 메시지를 받을 수 있고 같은 책임을 가지고 있다고 해서
모두 같은 방식으로 책임을 수행하지는 않습니다.
객체지향 세계에서는 객체들의 자율성이 보장되기 때문에,
각 객체들은 자율적으로 요청받은 메시지를 어떻게 수행할지 스스로 선택합니다.
메시지와 메서드
어떤 두 객체 모두 하나의 같은 메시지를 받을 수 있다 하더라도,
그것을 처리하는 메서드는 객체 스스로 선택하며, 객체마다 다를 수 있다.
객체들의 협력은 메시지를 통해 이뤄집니다.
즉, 한 객체가 다른 객체에게 명령이 아닌 요청을 보낸다는 의미이고,
그 요청을 어떻게 수행할지는 메시지를 받은 객체에게 달려있습니다.
가령 한식 요리사에게 prepareDinner() 라는 메시지를 보내면 한식을 내오고,
양식 요리사에게 prepareDinner() 라는 메시지를 보내면 양식을 내올 수 있다는 겁니다.
위 예시에서 prepareDinner() 는 메시지에 해당하고,
각 요리사의 내부 구현은 메서드에 해당합니다.
같은 메시지를 받을 수 있다, 같은 책임이 있다 라고 할 수는 있지만,
그것을 수행하는 메서드(내부 구현)는 스스로 선택하게 함으로써 객체들의 자율성을 보장하는 것입니다.
역할
역할은 책임의 집합.
한 역할을 수행하기 위해 필요한 모든 책임을 수행할 수 있다는 것은 대체 가능성을 의미하기도 한다.
역할은 책임의 집합입니다.
판사라는 역할에 재판 열기, 증언 시키기, 판결하기 라는 세 가지 책임이 있다고 가정해보겠습니다.
원래는 왕이 세 가지 책임을 수행하며 판사 역할을 수행했는데, 왕이 잠시 다른 나라에 방문했다고 가정해보죠.
왕이 자리를 비운 사이 여왕이 판사 역할을 대체한다고 하겠습니다.
그렇다면 여왕도 판사 역할에 필요한 재판 열기, 증언 시키기, 판결하기
이 세가지 책임을 모두 수행할 수 있는 충분한 지식과 행동이 있다는 의미입니다.
이러한 역할에 의한 대체 가능성은 단순성, 유연성, 재사용성을 가져다주는데요,
재판을 요청하는 객체 입장에서는 판사 역할을 수행하는 객체가 왕인지 여왕인지는 중요하지 않기 때문입니다.
단지, 그 객체가 재판 열기, 증언 시키기, 판결하기 세 가지 메시지를 받을 수 있는지만 확인하면 됩니다.
TDD를 한다면 한 객체가 있다고 가정하고, 그 객체에게 메시지를 보내는 코드를 먼저 작성하게 되는데요,
이 과정은 그 객체의 책임들을 발견하는 과정이고, 이 책임이 모여서 하나의 역할이 되는 것입니다.
객체의 자율성
한 객체는 자신 외 객체의 상태에 직접 접근하거나 변경할 수 없다.
이를 통해 각 객체의 자율성을 보장한다.
행동은 상태에 의존적입니다.
가령 자판기에 투입된 돈이 없다면, 버튼을 눌러도 음료는 나오지 않습니다.
그러나 충분한 돈이 투입된 뒤 버튼을 누른다면, 음료가 나옵니다.
또 반대로 행동은 상태를 변경시킵니다.
1000원을 투입한 자판기에 1000원자리 음료를 선택했다면 잔액은 0원이 됩니다.
이후에는 다시 음료를 선택해도 음료가 나오지 않습니다.
이 과정에서 자판기의 상태는 잔액 없음 -> 1000원 -> 잔액 없음 으로 바뀌어갔는데요,
외부에서 강제적으로 상태를 변경한 것이 아니라 돈을 받아주세요, 음료수를 주세요
라는 메시지를 받아 자판기가 처리하는 과정에서 자신의 상태를 스스로 변경한 것으로 봐야 합니다.
만약 자판기의 상태를 외부에서 강제로 10000원으로 변경할 수 있다면 어떨까요?
자판기가 자신의 역할을 스스로 제대로 해낼 수 있다고 생각할 수 있을까요?
협력하는 객체들의 공동체를 살아가는 존재가 아니라, 기계장치로 전락해버리는 결과일 것입니다.
따라서 객체의 상태를 외부에서 직접 접근하거나 변경하는 것을 막아야 합니다.
또한 객체가 자신의 상태를 스스로 책임지게 해야 합니다.
단지 메시지를 받아 처리하게 함으로써, 객체의 자율성이 보장되고, 프로그램 전체의 품질이 향상될 수 있습니다.
체크해볼만한 오해 세 가지
쉽게 오해할 수 있는 지점 중, 제가 주목한 세 가지를 골라봤습니다~!
오해 1. 객체지향은 현실 세계 모방이다?
현실 세계를 그대로 모방하는 것은 아닙니다.
개념적 설계를 위해 도메인 설계 과정에서 현실 세계를 은유 합니다.
그리고 이를 객체지향적인 세계로 재창조해냅니다.
현실 세계에서 불가능한 것이 객체지향 세계에서 가능하기도 하고,
그 반대의 경우도 성립합니다.
오해 2. 객체 설계 시 현실 세계를 모방하면 된다?
객체 설계의 핵심은 객체의 행동입니다.
그 객체가 어떤 메시지를 받을 수 있게 할 것인지,
그 메시지들, 즉 책임들이 모여 어떤 역할을 갖는 객체로 설정할 것인지가 핵심입니다.
(어떤 상태값을 갖는지가 아님에 주의해야 합니다)
오해 3. TDD는 테스트 중심 개발 기법이다?
TDD는 설계 기법입니다.
즉, 테스트 코드는 부수적으로 따라오는 보너스 같은 것이지 핵심이 아닙니다.
핵심은 어떤 객체가 존재한다고 가정하고
메시지를 보내고 응답값을 받는 과정을 먼저 설계하며
객체의 책임과 역할을 발견하고 피드백을 받으며 설계하는 것입니다.
소감
용어에 대한 개념을 잡고 갈 수 있어서 가장 좋았네요!
책임, 역할, 메시지, 메서드, 협력, 자율성, 객체 등등..
아주 중요하고 빈번하게 사용되지만 정확히 이해하지 못하고 있었던 단어들에 대해
확실히 이해를 더하고 갈 수 있던 점이 이 책이 준 가장 큰 선물인 것 같습니다!
약간 아쉬운 점은, 저의 객체지향적 사고의 수준이 아직 초보 단계여서,
이 책이 가져다 줄 수 있는 깊이의 일부만 흡수할 수 있었던 부분입니다.
레벨 2를 마칠 즈음에 다시 한 번 읽어보면
그땐 좀 더 쉽게 읽히는 부분도 있고, 더 깊이 깨달아지는 부분도 있을 것 같아요.
역할과 책임이 뭐가 다른지 가장 궁금했었는데 이것이 해결된 것이 아주 좋습니다.
메시지와 메서드를 같은 걸로 생각하고 있었는데 개념적 차이에 대해 발견해서 기뻤습니다.
객체의 자율성이 무엇이고 그것이 왜 필요한지에 대해서는 이해를 더할 수 있어서 좋았습니다.
이 부분은 조금 더 내공이 생기면 더 깊이 깨달아질 수 있을 것 같아요.
정말 레벨 1에서 꼭 읽고 가야하는 책이 맞는 것 같습니다.
감사합니다 우테코!!
p.s 독서회 발표를 위해 준비했던 간단한 pdf파일을 첨부했습니다.
'우아한테크코스 4기' 카테고리의 다른 글
다중 행 Insert 최적화 (Level 1 체스 미션 초기 체스판 구성) (2) | 2022.04.09 |
---|---|
🤔 도메인(domain)은 무슨 뜻일까?! (2) | 2022.03.25 |
💻 코딩을 지탱하는 기술을 읽었습니당 ! (4) | 2022.03.08 |
🏎️자동차 경주와 💸로또에서 배운 것들 (2) | 2022.03.08 |
컬렉션의 복사 방법을 정리해봅시다! (unmodifiable view / list) (6) | 2022.02.28 |