티스토리 뷰
종종 들어보기만 했던 이 책이 참 궁금했다. 객체지향의 사실과 오해. 객체들을 어떠한 협력 관계로 바라보아야 하는것인지.
이 책을 읽어나가면서 기억하고 싶은 부분들을 발췌해서 메모해본다.
객체지향으로 향하는 첫 걸음은?
1. 클래스가 아니라 객체를 바라보는 것에서 부터 시작한다.
2. 객체를 독립적인 존재가 아니라 기능을 구현하기 위해 협력하는 공동체의 존재로 바라보는 것이다.
3. 협력에 참여하는 객체들에게 얼마나 적절한 역할과 책임을 부여할 수 있는가.
4. 앞에서 설명한 개념들을 우리가 사용하는 프로그래밍 언어라는 틀에 흐트러짐 없이 담아낼 수 있는가.
1장 - 객체지향 패러다임의 핵심이 자율적인 객체들의 협력이라는 사실
2장 - '객체란 무엇인가' 객체가 상태와 행동, 식별자를 가진 존재라는 사실
3장 - 소프트웨어 개발에서 가장 중요한 개념인 추상화. 추상화는 단순화를 의미. 객체지향 패러다임에서 가장 널리 사용되는 추상화는 동적인 객체들을 단순화시켜 정적인 타입으로 갈무리하는 것.
4장 - 객체지향 설계의 가장 중요한 재료인 역할, 책임, 협력에 관해 설명. 객체들은 협력에 참여하기 위해 특정한 역할을 맡고 역할에 적합한 책임을 수행.
5장 - 훌륭한 메시지가 훌륭한 객체지향 설계의 기반이라는 사실**
6장 - 객체들의 구조안에 기능을 녹임으로써 변화에 안정적인 소프트웨어를 개발. 도메인 모델과 객체지향 패러다임 사이의 관계를 이해.
7장 - 코드를 통해 정리
[ 역할과 책임 ]
사람들은 다른사람과 협력하는 과정 속에서 특정한 역할(role)을 부여받는다.
역할은 어떤 협력에 참여하는 특정한 사람이 협력 안에서 차지하는 책임이나 임무를 의미한다.
역할이라는 단어는 의미적으로 책임이라는 개념을 내포한다.
특정한 역할은 특정한 책임을 암시한다. 협력에 참여하며 특정한 역할을 수행하는 사람들은 역할에 적합한 책임을 수행하게 된다.
역할과 책임은 협력이 원활하게 진행되는데 필요한 핵심적인 구성 요소다.
- 여러 객체가 동일한 역할을 수행할 수 있다.
- 역할은 대체 가능성을 의미한다.
- 각 객체는 책임을 수행하는 방법을 자율적으로 선택할 수 있다.
- 하나의 객체가 동시에 여러 역할을 수행할 수 있다.
객체, 역할, 책임, 협력
객체지향 어플리케이션의 윤곽을 결정하는 것은 역할, 책임, 협력이지만 실제로 협력에 참여하는 주체는 객체다.
객체지향을 객체지향이라고 부르는 이유는 패러다임의 중심에 객체가 있기 때문이다.
협력 공동체의 일원으로서 객체는 다음과 같은 두 가지 덕목을 갖춰야 하며, 두 덕목 사이에서 균형을 유지해야 한다.
첫째, 객체는 충분히 '협력적'이어야 한다.
두번째, 객체는 충분히 '자율적'이어야 한다.
인간 사회는 자율적인 존재로 구성된 협력 공동체다.
객체의 사회도 인간의 사회와 유사하다. 객체 공동체에 속한 객체들은 공동의 목표를 달성하기 위해 협력에 참여하지만 스스로의 결정과 판단에 따라 행동하는 자율적인 존재다.
객체지향 설계의 묘미는 다른 객체와 조화롭게 협력할 수 있을 만큼 충분히 개방적인 동시에 협력에 참여하는 방법을 스스로 결정할 수 있을 만큼 충분히 자율적인 객체들의 공동체를 설계하는 데 있다.
상태와 행동을 함께 지닌 자율적인 객체
흔히 객체를 상태(state)와 행동(behavior)을 함께 지닌 실체라고 정의한다. 이 말은 객체가 협력에 참여하기 위해 어떤 행동을 해야 한다면 그 행동을 하는 데 필요한 상태도 함께 지니고 있어야 한다는 것을 의미한다.
객체가 협력에 참여하는 과정 속에서 스스로 판단하고 스스로 결정하는 자율적인 존재로 남기 위해서는 필요한 행동과 상태를 함께 지니고 있어야 한다.
객체의 자율성은 객체의 내부와 외부를 명확하게 구분하는 것으로부터 나온다. 객체의 관점에서 자율성이란 자신의 상태를 직접 관리하고 상태를 기반으로 스스로 판단하고 행동할 수 있음을 의미한다. 객체는 행동을 위해 필요한 상태를 포함하는 동시에 특정한 행동을 수행하는 방법을 스스로 결정할 수 있어야 한다. 따라서 객체는 상태와 행위를 하나의 단위로 묶는 자율적인 존재다.
자율적인 객체로 구성된 공동체는 유지보수가 쉽고 재사용이 용이한 시스템을 구축할 수 있는 가능성을 제시한다.
협력과 메시지
객체지향의 세계에서는 오직 한 가지 의사소통 수단만이 존재한다. 이를 메시지라고 한다. 객체는 협력을 위해 다른 객체에게 메시지를 전송하고 다른 객체로부터 메시지를 수신한다.
메서드와 자율성
객체는 다른 객체와 협력하기 위해서 메시지를 전송한다. 수신자는 먼저 수신된 메시지를 이해할 수 있는지 여부를 판단한 후 미리 정해진 자신만의 방법에 따라 메시지를 처리한다. 이처럼 객체가 수신된 메시지를 처리하는 방법을 메서드(method)라고 부른다.
메시지와 메서드의 분리는 객체의 협력에 참여하는 객체들 간의 자율성을 증진시킨다.
외부의 요청이 무엇인지를 표현하는 메시지와 요청에 처리하기 위한 구체적인 방법인 메서드를 분리하는 것은 객체의 자율성을 높이는 핵심 메커니즘이다. 이것은 캡슐화(encapsulation)라는 개념과도 깊이 관련돼 있다.
객체지향이란 시스템을 상호작용하는 자율적인 객체들의 공동체로 바라보고 객체를 이용해 시스템을 분할하는 방법이다.
자율적인 객체란 상태와 행위를 함께 지니며 스스로 자기 자신을 책임지는 객체를 의미한다.
객체는 시스템의 행위를 구현하기 위해 다른 객체와 협력한다. 각 객체는 협력 내에서 정해진 역할을 수행하며 역할은 관련된 책임의 집합이다.
객체는 다른 객체와 협력하기 위해 메시지를 전송하고, 메시지를 수신한 객체는 메시지를 처리하는 데 적합한 메서드를 자율적으로 선택한다.
훌륭한 객체지향 설계자가 되기 위해 거쳐야 할 첫 번째 도전은 코드를 담는 클래스의 관점에서 메시지를 주고받는 객체의 관점으로 사고의 중심을 전환하는 것이다.
중요한 것은 어떤 클래스가 필요한가가 아니라 어떤 객체들이 어떤 메세지를 주고받으며 협력하는가다. 클래스는 객체들의 협력 관계를 코드로 옮기는 도구에 불과하다.
객체지향의 핵심은 클래스가 아니다. 핵심은 적절한 책임을 수행하는 역할 간의 유연하고 견고한 협력 관계를 구축하는 것이다. 클래스는 협력에 참여하는 객체를 만드는 데 필요한 구현 메커니즘일 뿐이다. 객체지향의 중심에는 클래스가 아니라 객체가 위치하며, 중요한 것은 클래스들의 정적인 관계가 아니라 메시지를 주고받는 객체들의 동적인 관계다.
객체의 역할, 책임, 협력에 집중하라.
도메인 모델
소프트웨어를 사용하는 사람들은 자신이 관심을 가지고 있는 특정한 분야의 문제를 해결하기 위해 소프트웨어를 사용한다. 이처럼 사용자가 프로그램을 사용하는 대상 분야를 도메인 이라고 한다.
도메인 모델이란 사용자가 프로그램 사용하는 대상 영역에 관한 지식을 선택적으로 단순화하고 의식적으로 구조화한 형태이다. 소프트웨어가 목적하는 영역 내의 개념과 개념 간의 관계, 다양한 규칙이나 제약 등을 주의 깊게 추상화한 것이다. 도메인 모델은 소프트웨어 개발과 관련된 이해관계자들이 도메인에 대해 생각하는 관점이다.
도메인모델은 단순히 다이어그램이 아니다. 도메인 모델은 이해관계자들이 바라보는 멘탈 모델인 것이다. 제품을 설계할 때 제품에 관한 모든 것이 사용자들이 제품에 대해 가지고 있는 멘탈 모델과 정확하게 일치해야 한다.
도널드노먼의 주장에 의하면 최종제품은 사용자의 관점을 반영해야 한다는 것이다. 최종코드는 사용자가 도메인을 바라보는 관점을 반영해야 한다. 곧 애플리케이션이 도메인 모델을 기반으로 설계돼야 한다는 것을 의미한다.
도메인모델이란 사용자들이 도메인을 바라보는 관점이며, 설계자가 시스템의 구조를 바라보는 관점인 동시에 소프트웨어 안에 구현된 코드의 모습 그 자체이기 때문이다.
객체지향을 사용하면 사용자들이 이해하고 있는 도메인의 구조와 최대한 유사하게 코드를 구조화할 수 있다. 동적인 객체가 가진 복잡성을 극복하기 위해 정적인 타입을 이용해 세상을 단순화할 수 있으며 클래스라는 도구를 이용해 타입을 코드안으로 옮길 수 있다. 객체지향 패러다임은 사용자의 관점, 설계자의 관점, 코드의 모습을 모두 유사한 형태로 유지할 수 있게 하는 유용한 사고 도구와 프로그래밍 기법을 제공한다.
결과적으로 객체지향을 이용하면 도메인에 대한 사용자 모델, 디자인 모델, 시스템 이미지 모두가 유사한 모습을 유지하도록 만드는 것이 가능하다.
안타깝게도 대부분의 소프트웨어 도메인은 현실에 존재하지 않는 가상의 세계를 대상으로 한다.
그렇다면 우리가 은유를 통해 투영해야 하는 대상은 무엇인가? 그것은 바로 사용자가 도메인에 대해 생각하는 개념들이다. 소프트웨어 객체는 그 대상이 현실적인지, 현실적이지 않은지에 상관없이 도메인 모델을 통해 표현되는 도메인 객체들을 은유해야 한다. 이것이 도메인 모델이 중요한 이유다. 도메인 모델을 기반으로 설계하고 구현하는 것은 사용자가 도메인을 바라보는 관점을 그대로 코드에 반영할 수 있게 한다. 결과적으로 표현적 차이는 줄어들 것이며, 사용자의 멘탈 모델이 그대로 코드에 녹아 스며들게 될 것이다.
도메인 모델을 기반으로 코드를 작성하는 두 번째 이유는 도메인 모델이 제공하는 구조가 상대적으로 안정적이기 때문이다.
도메인 모델의 핵심은 사용자가 도메인을 바라보는 관점을 반영해 소프트웨어를 설계하고 구현하는 것이다. 사용자는 누구보다도 도메인의 '본질적인'측면을 가장 잘 이해하고 있기 때문이다. 본질적이라는 것은 변경이 적고 비교적 그 특성이 오랜 시간 유지된다는 것을 의미한다. 도메인모델은 소프트웨어 구조의 기반을 이룬다. 이 안정적인 구조를 기반으로 자주 변경되는 기능을 배치함으로써 기능의 변경에 대해 안정적인 소프트웨어를 구현할 수 있다.
결론적으로 안정적인 구조를 제공하는 도메인 모델을 기반으로 소프트웨어의 구조를 설계하면 변경에 유연하게 대응할 수 있는 탄력적인 소프트웨어를 만들 수 있다.
실제로 사용자에게 중요한 것은 소프트웨어의 기능이다. 소프트웨어의 존재 이유는 사용자가 원하는 목표를 달성할 수 있는 다양한 기능을 제공하는 것이다. 따라서 사용자에게 제공할 기능을 기술한 정보가 필요하다. 이렇게 소프트웨어의 기능을 기술하기 위해 유스케이스라는 유용한 기법을 사용한다.
사용자는 자신의 목표를 달성하기 위해 시스템과의 상호작용을 시작한다. 요청을 보내고 응답을 받으며 그 응답을 기반으로 또 다른 작업을 요청하고 시스템은 이 요청을 다시 처리한 후 사용자에게 응답한다.
이처럼 사용자의 목표를 달성하기 위해 사용자와 시스템 간에 이뤄지는 상호작용의 흐름을 텍스트로 정리한 것을 유스케이스 라고 한다.
유스케이스의 가치는 사용자들의 목표를 중심으로 시스템의 기능적인 요구사항들을 이야기 형식으로 묶을 수 있다는 점이다. 유스케이스는 단순히 기능을 나열하는 것이 아니라 이야기를 통해 연관된 기능들을 함께 묶을 수 있다.
유스케이스는 설계 기법도, 객체지향 기법도 아니다.
유스케이스는 단지 사용자가 바라보는 시스템의 외부 관점만을 표현한다는 점을 주목해야 한다. 유스케이스는 시스템의 내부 구조나 실행 메커니즘에 관한 어떤 정보도 제공하지 않는다. 단지 사용자가 시스템을 통해 무엇을 얻을 수 있고 어떻게 상호작용할 수 있느냐에 관한 정보만 기술된다. 유스케이스는 단지 기능적 요구사항을 사용자의 목표라는 문맥을 중심으로 묶기 위한 정리 기법일 뿐이다.
재료 합치기 : 기능과 구조의 통합
도메인 모델, 유스케이스, 그리고 책임-주도 설계
도메인 모델은 안정적인 구조를 개념화하기 위해, 유스케이스는 불안정한 기능을 서술하기 위해 가장 일반적으로 사용되는 도구이다. 변경에 유연한 소프트웨어를 만들기 위해서는 유스케이스에 정리된 시스템의 기능을 도메인 모델을 기반으로 한 객체들의 책임으로 분배해야한다.
시스템의 기능을 시스템의 책임으로 바꾼 후 얻어진다. 시스템에 할당된 커다란 책임은 시스템안의 작은 규모의 객체들이 수행해야 하는 더 작은 규모의 책임으로 세분화된다. 협력을 완성하는데 필요한 메시지를 식별하면서 객체들에게 책임을 할당해 나간다. 마지막으로 협력에 참여하는 객체를 구현하기 위해 클래스를 추가하고 속성과 함께 메서드를 구현하면 시스템의 기능이 완성된 것이다.
객체 설계는 가끔 다음과 같이 표현되기도 한다.
요구사항들을 식별하고 도메인 모델을 생성한 후, 소프트웨어 클래스에 메서드들을 추가하고, 요구사항을 충족시키기 위해 객체들 간의 메시지 전송을 정의하라[Larman 2001]
책임-주도 설계는 유스케이스로부터 첫 번째 메시지와 사용자가 달성하려는 목표를, 도메인 모델로부터 기능을 수용할 수 있는 안정적인 구조를 제공받아 실제로 동작하는 객체들의 협력 공동체를 창조한다.
책임-주도 설계는 시스템의 기능을 역할과 책임을 수행하는 객체들의 협력 관계로 바라보게 함으로써 두 가지 기본 재료인 유스케이스와 도메인 모델을 통합한다.
중요한 것은 견고한 객체지향 애플리케이션을 개발하기 위해서는 사용자의 관점에서 시스템의 기능을 명시하고, 사용자와 설계자가 공유하는 안정적인 구조를 기반으로 기능을 책임으로 변환하는 체계적인 절차를 따라야 한다는 것이다.
코드는 세가지 관점을 모두 제공해야 한다.
개념관점, 명세관점, 구현관점.
먼저 개념 관점에서 코드를 바라보면 클래스가 보이다.
명세 관점은 클래스의 인터페이스를 바라본다.
구현 관점은 클래스의 내부 구현을 바라본다.
훌륭햔 객체지향 프로그래머는 하나의 클래스 안에 세 가지 관점을 모두 포함하면서도 각 관점에 대응되는 요소를 명확하고 깔끔하게 드러낼 수 있다.
다시 한 번 강조한다. 인터페이스와 구현을 분리하라.
명세 관점은 클래스의 안정적인 측면을 드러내야 한다. 구현 관점은 클래스의 불안정한 측면을 드러내야 한다. 마틴 파울러는 명세 관점과 구현 관점을 분리하는 것이 매우 중요하다고 주장한다. 중요한 것은 여러분이 클래스를 봤을 때 클래스를 명세 관점과 구현 관점으로 나눠볼 수 있어야 한다는 것이다.
추상화 기법
추상화는 도메인의 복잡성을 단순화하고 직관적인 멘탈 모델을 만드는 데 사용할수 있는 가장 기본적인 인지 수단이다.
- 분류와 인스턴스화
- 일반화와 특수화
- 집합과 분해
현재의 객체지향 패러다임은 아리스토텔레스의 분류법의 근간을 형성하는 아이디어를 기반으로 한다. 만약 객체들이 동일한 특성을 가진다면 그것은 동일한 카테고리에 속한다. 따라서 객체들의 카테고리는 객체들이 공유하는 공통적인 특성에 의해 정의된다.
클래스 기반의 객체지향 언어는 아리스토텔레스의 철학을 기반으로 한다. 클래스는 객체가 공유하는 본질적인 속성을 정의한다. 대부분의 객체지향 프로그래밍 언어에서 동일한 범주에 속하는 객체는 동일한 클래스의 인스턴스여야 한다. 대부분의 객체지향 언어는 본질적인 속성은 표현할 수 있지만 우연적인 속성은 표현할 수 없다. 따라서 동일한 범주에 속하는 객체는 모두 동일한 속성을 가져야만 한다.
아리스토텔레스는 세계에 존재하는 객체들에 대한 객관적인 분류 체계가 존재한다고 가정했다. 아리스토텔레스의 작업은 적어도 서양과 다른 여러 문화권에서 자연계에는 하나의 정확한 분류 체계가 존재한다는 광범위하게 수용돼 온 아이디어의 기반이 되었다 .안타깝게도 분류의 수준과 결과는 누가 분류를 하는가와 무엇을 기반으로 분류하는가에 따라 크게 달라진다. 실제로 사람들은 동일한 사물을 다양한 방식으로 인식하며 다양한 방식으로 분류한다.
'ALL' 카테고리의 다른 글
[Rust] macOS / 리눅스에 설치 (0) | 2023.06.30 |
---|---|
jsp내에서 JSTL과 스트립트의 실행 시점 (0) | 2023.04.25 |
API 란? (0) | 2023.01.02 |
2022 회고록 (0) | 2023.01.01 |
[React] useState 간단예제 카운터 (0) | 2022.12.29 |
- Total
- Today
- Yesterday
- node
- 친절한SQL튜닝
- security
- 자바의정석
- 한입크기로 잘라먹는 리액트
- 스프링 프로젝트
- 스프링의정석
- 스프링 빈
- 데브캠프
- 시큐리티
- 자바스크립트
- React
- Spark
- 인덱스
- MySQL
- @Configuration
- 컨테이너
- 코드로 배우는 스프링 웹 프로젝트
- 남궁성
- 리액트
- EC2
- 객체지향
- JavaScript
- 이정환
- 데이터베이스
- Node.js
- spring
- 스프링
- di
- AWS
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |