객체지향 패러다임은 지식을 추상화하고 추상화한 지식을 객체 안에 캡슐화함으로써 실세계 문제에 내재된 복잡성을 관리하려고 한다. 객체를 발견하고 창조하는 것은 지식과 행동을 구조화하는 문제다.
- 레베카 워프스브록(Rebecca wirts-Brock)-
이번 장에서는 객체를 상태와 행동으로 구분함으로써 은유를 이용해 객체를 의인화함으로써 객체를 쳐다보는 관점에 대한 이야기가 주를 이루고 있다.
처음에는 아기가 가림막에 가려진 막대기를 바라보는 관점의 예시로 시작한다.
가림막 뒤에 막대기가 위 아래로 2부분이 보일 때, 대부분의 사람이라면 긴 막대기 1개가 뒤에 있구나. 라고 생각하는 것이 일반적이다.
하지만, 가림막 뒤에 있던 막대기가 알고보니 2개였다면? 당황스러울 것이다. 나 또한 읽으면서 그랬을 것 같다는 생각을 했다.
이렇듯 사람은 태어난 지 얼마 되지 않았음에도 뚜렷한 경계를 가지고 행동하는 물체를 하나의 개념으로 인지한다는 사실에 대해서 설명한다.
이 파트에서는 사람들이 객체지향을 직관적이고 이해하기 쉬운 패러다임으로 얘기하는 이유를 객체지향이 세상을 자율적이고 독립적인 객체들로 분해할 수 있는 인간의 기본적인 인지능력에 기반하기 때문이라고 한다.
사람은 분해를 하는 과정에서 물리적인 것 말고도 추상적인 것 또한 경계를 지을 수 있다. 예를 들어서, 계좌의 입 출금 또한우리는 뚜렷하게 경계 지어서 판단을 할 수가 있다.
하지만 현실세계와 소프트웨어 세계의 유사성은 여기까지이고, 여기서 객체지향 패러다임의 목적이 나온다.
객체지향 패러타임이란 현실 세계를 모방하는 것이 아니라 현실 세계를 기반으로 새로운 세계를 창조하는 것
따라서, 현실 세계와는 다르게 돌아갈 수 있다.
한 가지 간단한 예시로, 현실 세계에서 전등의 불이 켜지거나 꺼질려면 사람의 직접적인 개입이 있어야 하지만 소프트웨어 세계에서 전구라는 객체는 자율적으로 불을 껏다 킬수 있는 기능을 가지고 있다.
이 책에서 가장 인상깊은 부분은 이상한 나라의 앨리스(우리가 아는 그 소설)를 가지고 객체지향에 대해서 설명을 해주는데 정말 좋은 예시라고 생각한다.
앨리스가 이상한 나라로 들어가는 과정을 행돈 간의 순서로 표현을 했는데 이 부분으로 객체의 대한 특징을 설명해준다.
행동에 의해서 객체의 상태가 변경이 되더라도 그 객체의 이전에 존재하던 그 객체라는 것 즉, 상태 변경과 무관하게 유일한 존재로 식별 가능하다는 것
위의 이야기를 바탕으로 객체의 특징을 살펴볼 수 있다.
1. 객체는 상태를 가지며 상태는 변경이 가능하다. (상태)
2. 앨리스의 상태를 변경시키는 것은 앨리스의 행동이다. (행동)
- 행동의 결과는 상태의 의존적이며 상태를 이용해 서술 할 수 있다.
- 행동의 순서가 결과에 영향을 미친다.
3. 앨리스는 어떤 상태에 있더라도 유일하게 식별 가능하다. (식별자)
즉, 객체를 설명하는 부분에 있어서 상태, 행동, 식별자를 지닌 실체로 본다면 효과적으로 이해할 수 있다.
상태
상태가 존재해야 하는 이유는 다음과 같다. 우리가 코드를 짜더라도 과거에 발생한 행동의 이력을 하나 하나 확인하면서 이어서 발생할 행동에 판단하는 것은 거의 현대에 와서는 딥러닝이 이러한 것을 해결 할 수 있을 것이다.
하지만, 일반적인 개발자가 위와 같은 내용을 판단하기란 쉽지 않다.
하지만 상태를 이용하면 과거의 모든 행동 이력을 설명하지 않고도 행동의 결과를 쉽게 예측할 수 있다.
여기서 상태와 프로퍼티가 나온다.
보통 숫자, 문자열, 양, 속도, 시간, 날짜, 참/거짓 같은 단순한 값들을 객체로 표현하지 않고, 이러한 것들은 다른 객체의 상태를 표현하기 위해 사용된다. 즉 위와 같은 것들은 상태라고 할 수 있다.
그럼 상태는 무엇이고 프로퍼티는 무엇일까.
일반적으로 모든 객체의 상태는 단순한 값과 객체의 조합으로 표현할 수 있다.
이때 객체의 상태를 구성하는 모든 특징을 통틀어서 프로퍼티(Property) 라고 하고, 그 상태의 값을 프로퍼티 값(Property Value)라고 한다.
이 말이 이해하기 어려울 수 있는데 프로퍼티는 정적이고 프로퍼티 값을 동적이라고 하는데
프로퍼티를 상태의 변수명, 프로퍼티 값을 변수의 값 이라고 생각하면 된다.
이어서 링크라는 말이 나오는데, 링크란 객체와 객체 사이의 의미 있는 연결이라고 한다. 객체는 링크를 통해서만 메시지를 전송할 수 있다. 즉, 링크는 객체가 다른 객체를 참조 할 수 있게 해주는 것을 의미한다.
이러한 것이 가능하기 위해서는 Composite 형식을 사용해야 할 것이다.
즉, 객체의 프로퍼티는 단순한 값인 속성과 다른 객체를 가리키는 링크라는 두 가지 종류의 조합으로 표현할 수 있다.
링크는 어렵게 생각할 것 없이 객체가 Composite 관계임을 이해하는 것이 제일 이해하기 좋을 것 같다.
객체의 행동은 다른 객체로 하여금 간접적으로 객체의 상태를 변경하게 하는 것이 가능하다.
이렇듯 객체의 기본적인 사상은 상태와 상태를 조작하기 위한 행동을 하나의 단위로 묶는 것이다.
객체의 상태를 변경하는 것은 객체의 자율성으로 인한 자발적인 행동뿐인데, 객체의 행동에 의해 객체의 상태가 변경되는 것을 부수 효과(side effect) 라고 한다고 한다.
이를 이용해 객체의 행동을 상태 변경의 관점에서 쉽게 이해할 수 있다.
위에서 봤던 행동의 결과는 객체의 상태에 의존적이라고 한 것은, 상태에 따라서 다르게 행동을 할 수 있기 때문이다.
상태와 행동 사이의 관계
1. 객체의 행동은 상태에 영향을 받는다.
2. 객체의 행동은 상태를 변경시킨다.
행동을 할 때 대체로 다른 객체와 협력을 하게 되는 상황이 많이 발생 할 것이다.
이러한 관점에서 협력과 행동을 살펴보자.
협력과 행동
객체는 자율성을 가지고 있고 객체는 역할에 대한 책임을 완수하기 위해서 다른 객체를 이용하고 이어서 다른 객체에게 서비스를 제공한다.
객체지향 특징 중 가장 중요한 객체가 다른 객체와 협력하기 위한 방법은 다른 객체에게 요청을 보내는 것이다.
즉, 객체가 다른 객체와 협력을 하기 위해서는 메시지를 통해서만 의사소통 할 수 있다는 것이다.
이 부분은 이 책의 후반부에까지 자주 강조되는 부분이기 때문에 객체가 메시지를 통해서 의사소통 할 수 있다는 것을 주의깊게 보자.
객체의 행동으로 인해서 발생하는 결과를 책에서는 두 가지 관점에서 설명한다.
1. 객체 자신의 상태 변경
2. 행동 내에서 협력하는 다른 객체에 대한 메시지 전송
상태 캡슐화
이어서 상태 캡슐화라는 얘기가 나온다. 항상 캡슐화에 대한 개념을 공부하면서 단순히 상태와 어떠한 행위를 메서드로 묶고, 이를 이용해 다른 객체가 이 행위가 무엇인지 알 수 없도록 한다. 라고만 이해를 하고 왜 이래야 하는지 정확하게 감이 안왔지만 책을 보고 깨달음을 얻을 수 있었다.
객체지향 세계에서는 모든 객체는 자신의 상태를 스스로 관리하는 자율적인 존재이다.
이 부분이 캡슐화를 하는 가장 큰 이유이다. 자신의 상태는 객체 스스로가 관리해야 하기 때문에, 외부의 객체가 자율적으로 관리되고 있는 다른 객체의 상태를 바꾼다는 것은 객체지향 패러다임에서 어긋나는 행동이다.
즉, 메시지를 송신하는 객체가 메시지를 수신하는 객체의 상태 변화에 대해서는 알면 안된다는 것이 캡슐화의 특징이다.
외부에서 객체는 무조건 행동으로만 메시지를 주고 받을 수 있어야 한다.
따라서, 캡슐화를 하는 이유는 객체의 자율성을 높이기 위한 방법이고, 이는 협력에 참여하는 객체들이 유연하고 간결해진다는 큰 특징을 가지고 있다.
식별자
식별자는 객체를 서로 구별할 수 있는 특정한 프로퍼티가 객체 안에 존재한다는 것을 말한다고 한다.
여기서는 동일성과 동등성에 대해서 얘기를 한다. 우리가 정적으로 적힌 코드에는 없지만 우리는 객체를 서로 구별 할 수 있는 프로퍼티를 hashcode() 와 equals() 를 이용해 구분한다는 사실을 알고 있다.
흔히 상태를 이용해 두 값이 판단할 수 있는 성질을 동등성(equals) 라고 하고, 두 객체의 상태가 다르더라도 식별자를 기반으로 객체가 같은지를 판단 할 수 있는 성질을 동일성(identical) 이라고 한다.
주로 값과 객체라고 표현했을 때, 문맥에 따라 그 의미가 혼란스러워 질 수 있기 때문에, 별도의 용어를 사용하는데
주로 객체는 참조 객체(reference object), 엔티티(entity) 라고 표현을 하고, 값 객체(value object)는 식별자를 가지지 않는 값을 가리키는 용어이다.
기계적인 관점에서의 객체
개발자들의 주된 업무는 객체의 상태를 조회하고 객체의 상태를 변경하는 일이 주된 업무이다.
이 과정에서 객체의 상태를 조회하는 작업을 쿼리(query) 라고 하고, 객체의 상태를 변경하는 작업을 명령(command) 라고 한다.
상태는 행동에 의해서만 변경되어야 하기 때문에 여기서 명령을 행동이라고 이해해도 무방 할 것 같다.
마지막으로 객체지향에 설계에 대한 함정에 대해서 설명한다. 나도 이 책을 읽기전까지는 책에서 말하는 내용과 동일하게 생각하고 있었다.
어떠한 객체를 생성했을 때, 초보자들은 주로 상태를 중심으로 객체를 바라본다. 객체가 필요한 상태가 무엇인지, 그리고 그 상태에 따라서 필요한 행동을 결정하는 방식이다.
그러나 위와 같은 설계 방식은 나쁜 영향을 미친다.
1. 상태를 먼저 결정할 경우 캡슐화가 저해된다.
2. 객체를 협력자가 아닌 고립된 섬으로 만든다.
3. 객체의 재사용성이 저하된다.
객체를 설계하는데 있어서 가장 주의해야 할 부분은 객체는 다른 객체와 협력하기 위해 존재하고, 객체는 메시지를 요청하고 응답함으로써 객체 각각이 자율적으로 행동해야 한다는 것이다.
따라서, 객체를 설계할 때에는 애플리케이션에서 필요한 협력에 대해서 생각하고 협력에 참여하는데 필요한 행동을 생각한 후에 행동을 수행 할 객체를 선택하고, 이 이후에 그 객체에 행동에 대해서 정의를 한 후에 필요한 상태를 기술하는 것이 옳은 방법이다.
이러한 방식을 책임-주도 설계(Responsibility-Driven Design, RDD) 라고 하고, 협력이라는 문맥 안에서 객체의 행동을 생각하도록 도움으로써 응집도 높고 재사용 가능한 객체를 만드는 것이다.
테스트-주도 개발(Test-Driven Development, TDD)은 위의 책임-주도 설계를 잘 하기 위한 일종의 개발 방법이라는 것을 이 책을 읽고 나서 알게되었다.
이전까지는 단순히 개발의 유지보수성을 높이기 위해서라고 생각하고 있었다..
마지막으로 1장에서도 클래스란 도시전설에 대해서 얘기를 했는데, 이번 장에서는 추상화에 대한 도시전설에 대해서 얘기를 한다.
소프트웨어 개발자는 실제 객체들의 특징을 간추리고 요약해서 소프트웨어 객체로 추상화할 수 있는 능력이 중요하다는 생각
이 생각이 바로 잘못된 생각이다.
의인화
소프트웨어에서는 현실 세계에서 어떤 객체가 하지 못하는 행동을 가능하게 할 수 있다.
예를 들어서, 상품이라는 객체가 직접 가격을 계산하게 하는 일도 할 수 있는 것이다.
처음에 얘기한 현실 세계에 대한 객체를 모방하는 것이 아닌, 새로운 세계를 창조하고 현실의 객체보다 더 많이 할 수 있게 만드는 것이다. 이러한 특징을 책에서는 객체의 의인화로 얘기하고 있고, 현실 세계의 객체와 객체 지향 세계 사이의 관계를 은유적으로 바라봐야 한다는 것이다.
'도서 > 객체 지향의 사실과 오해' 카테고리의 다른 글
[객체지향의 사실과 오해] 4. 역할, 책임, 협력 (0) | 2023.04.25 |
---|---|
[객체지향의 사실과 오해] 3. 타입과 추상화 (0) | 2023.04.23 |
[객체지향의 사실과 오해] 협력하는 객체들의 공동체 (0) | 2023.04.19 |