Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions 이현희/AppendixA.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# 7장

## 요약
1. 객체지향설계와 그 결과물인 코드는 3가지의 관점이 있다. 개념, 명세, 구현
2. 도메인 모델 ~ 최종 구현까지는 1. 도메인 만들기 / 2. 협력 디자인하기 / 3. 구현하기 의 단계를 거친다.

## 추상화 기법
추상화 -> 도메인의 복잡성 단순화, 직관적 멘탈 모델 제작에 도움

종류
- 분류/인스턴스화
- 일반화/특수화
- 집합/분해

분석, 설계, 구현 단계에서 일관성있게 적용가능

## 분류/인스턴스화
객체를 분류하고 범주로 묶는 것 = 객체들의 집합에 공통 "개념"을 적용하는 것<br>
개념 = 유사한 객체들에게 공통적으로 적용되는 관념<br>
분류한다 = 범주라는 렌즈로 세상을 본다 = 객체에 개념을 적용한다 = 객체를 개념을 나타내는 집합의 요소로 포함시킨다.

개념 = 공통 특성을 가진 객체의 집합<br>
개념과 타입은 아예 같은 말<br>
객체는 타입의 인스턴스임.

객체, 곧 "타입"의 3가지 정의
- 심볼 : 이름
- 내연 : 의미
- 외연 : 집합

분류의 종류
- 단일 분류 : 객체가 한 시점에 한 타입을 가짐
- 다중 분류 : 객체가 한 시점에 여러 타입을 가짐

프로그래밍 언어는 단일 분류만을 지원함.<br>
다중 분류는 다중 상속과는 다름.<br>

- 다중 상속 : 하나의 타입이 여러 슈퍼 타입을 가짐
- 다중 분류 : 하나의 타입이 아님. 하나의 객체가 여러 타입을 가짐

- 동적 분류 : 객체의 타입이 바뀔 수 있음
- 정적 분류 : 객체의 타입이 바뀔 수 없

프로그래밍 언어는 정적분류만을 지원함.

클래스는 타입을 구현하는 방법 중 하나일 뿐.<br>
다른 방법으로는 추상 클래스, 인터페이스가 있음.

## 일반화/특수화
범주 즉 타입 간에는 계층이 있음.
상위 타입(슈퍼타입)을 하위 타입의 일반화라고 하고,
하위 타입(서브타입)을 상위 타입의 특수화라고 함.

내연의 관점에서 서브타입이 되려면(100% 규칙), 슈퍼타입의 의미를 100% 가지고 있어야 함.<br>
외연의 관점에서 서브타입이 되려면(is-a), 슈퍼타입의 부분집합이어야 함.

일반화가 되려면, 서브타입은 슈퍼타입에 구조적/행위적 순응을 해야함<br>
순응 = 대체 가능성<br>
구조적 순응은 "속성, 연관관계"가 대체가능해야 한다는 것<br>
행위적 순응은 "행위"가 대체가능해야 한다는 것

상속은 서브타이핑, 서브클래싱으로 구분됨.
- 서브타이핑 : 대체가능함. 설계유연성이 목적. =인터페이스 상속
- 서브클래싱 : 대체불가능함. 코드 재사용이 목적. =구현 상속

상속이라고 무조건 대체 가능성을 보장하는 서브타이핑이 아니고,<br>
내부적으로 그냥 코드 재사용을 위해 쓴 것일 수도 있음

가상함수로만 넘겨주면 서브타이핑인 셈이고,<br>
구현된 함수를 넘겨주면 그 함수를 재사용하기 위한 서브클래싱일 수 있음

상속 계층에서 메시지를 이해하는 법 "위임"<br>
내가 처리하지 못하는 메시지는 부모에게 넘긴다.

## 집합/분해
복잡성은 계층의 형태로 표현가능하다.<br>
중간계층이 있으면 더 쉽게 이해할 수 있다.

집합 = 부분으로부터 전체를 만들어내는 것
분해 = 그 반대

중간계층이 여러 개를 하나로 표현해줌 = 추상화
중간계층 아래는 굳이 볼 필요 없음 = 캡슐화

- 합성관계 : 부분과 전체 관계. 전체가 사라지면 부분도 사라짐(생명주기)
- 연관관계 : 부분과 전체가 아닌 그냥 관계. 한쪽이 사라져도, 다른 한쪽이 사라지지 않음(생명주기)
80 changes: 80 additions & 0 deletions 이현희/Chapter6.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# 6장

## 요약
1. 설계는 기능과 구조 2가지를 모두 고려하는 것이다.
2. 객체지향설계가 은유할 객체들은 도메인 모델에서, 객체지향설계가 분배할 책임은 유스케이스에서 나온다.

## 기능보다 구조가 안정적이다
길을 묻는 것과 지도의 예시

기능은 해결 지향적이고, 구조는 문제 지향적이다.

기능보다 구조가 더 바뀔 가능성이 적다. 따라서 구조를 바탕으로 모델을 만들어야 변경 수요가 적다.

설계는 기능(사용자에게 해줄 것, 충분조건)과 구조(제품의 형태, 필요조건)를 적절히 조화시키는 것.

착각하지 말아야 할 점은, 우리는 미래를 예측할 수 없기 때문에 설계 시에 어떤 변화를 예측하기 보다는,
변화를 적게 할 수 있도록 여지를 남기는 방향이 더 좋다.<br>
=> 이 여지를 남기는 방법이 바로 구조를 이용하는 것

## 객체지향 세계 설계를 위한 2가지 재료
객체지향 세계 설계를 위한 2가지 재료는 기능과 구조이다.

이 재료를 얻는 방법
- 기능 => 유스케이스 모델링
- 구조 => 도메인 모델

### 도메인 모델링
도메인 = 사용자가 프로그램을 사용하는 분야<br>
모델 = 필요한 정보만 선택해 단순화 한 것<br>
도메인 모델 = 소프트웨어가 사용되는 분야 내의 개념이나 관계 등을 단순화한 것

도메인 모델은 멘탈 모델의 일종<br>
멘탈모델이란 사람의 마음 속에 가지고 있는 관계/규칙/제약 모델(본능적으로 구축하는 모델이라고 봐도 될 듯)

멘탈모델은
- 사용자 모델(사용자 관점)
- 디자인 모델(설계 관점)
- 시스템 이미지(통합)
이렇게 3가지로 구성된다.

설계자는 디자인 모델과 사용자 모델을 통해 구축한 시스템 이미지(=제품)을 통해서 사용자의 피드백을 받을 수 있음.

좋은 제품은 사용자 모델을 전부 반영한 제품이고, 소프트웨어로 치면 좋은 코드는 사용자 모델을 전부 반영한 코드이다.

도메인 모델의 3가지 종류를 모델링할 수 있는 유일한 패러다임 = 객체지향<br>
심지어 3가지 종류가 다 비슷해질 수 있음 = 연결완전성

소프트웨어는 현실의 은유이다. 여기서 말하는 현실, 즉 은유의 대상이 바로 도메인 모델이다.<br>
즉 현실 그 자체가 아닌, 사람들이 현실을 보고 만들어낸 멘탈 모델을 옮겨야 하는 것.

도메인 모델은 안정적인 구조를 제공한다.<br>
왜냐하면 사람들은 도메인의 본질적인 것을 잘 알고 있고 이를 통해 멘탈 모델을 만든 것이기 떄문
- 비즈니스가 없어지거나 개편되지 않는 한 안정적으로 유지됨
- 개념 간의 관계는 비즈니스 규칙을 기반으로 하기 때문에 비즈니스 정책이 크게 변경되지 않는 한 안정적으로 유지됨

### 유스케이스 모델링
기능적 요구사항 = 시스템이 사용자에게 제공해야할 기능의 목록을 나열한 것

유스 케이스 모델링 = 사용자가 특정한 '목표'를 가지고 시스템과 '상호작용'하는 흐름을 텍스트로 묘사한 것<br>
사용자의 목표라는 관점을 통해서 그냥 나열된 기능들을 하나로 묶어줌 = 연관된 기능의 집합을 만들 수 있음<br>
한 번의 상호작용을 시나리오라고 함. 시나리오를 묶어주는 걸로도 볼 수 있음

- 다이어그램이 아니고 텍스트 형태임
- 인터페이스와 같이 자주 변하는 내용은 포함하지 않음
- 내부 설계에 대한 내용도 포함하지 않음
- 설계에 대한 힌트만 얻을 수 있을 뿐 일반적인 규칙(명사는 클래스 동사는 메소드 어쩌구..)은 얻을 수 없음

### 도메인 모델, 유스케이스, 책임 주도 설계의 관계
도메인 모델은 책임 주도 설계가 은유할 객체의 모델을 제시하고,<br>
유스케이스는 책임 주도 설계가 분배해야 하는 책임을 제시한다.

내가 책임 주도 설계 부분을 읽으면서, 협력 속에서 적합한 객체에게 적합한 책임을 분배해야한다는 말을 보고<br>
아니 그럼 객체 식별은 어케함??이라는 의문을 가졌었는데 이게 말끔히 해소된 것 같다.

기능적인 요구사항이 변경되면, 책임과 일부 객체 간 대응 관계만 변한다.
객체지향의 큰 장점은 바로, 도메인 모델링 기법 = 도메인을 코드로 옮기는 방법이라는 점이다.<br>
도메인 모델에서 코드로의 변환가능성을 연결완전성이라고 하고<br>
코드에서 도메인 모델로의 변환 가능성을 가역성이라고 한다.

결과적으로, 코드와 도메인 모델은 분리되지 않는다.
50 changes: 50 additions & 0 deletions 이현희/Chapter7.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# 7장

## 요약
1. 객체지향설계와 그 결과물인 코드는 3가지의 관점이 있다. 개념, 명세, 구현
2. 도메인 모델 ~ 최종 구현까지는 1. 도메인 만들기 / 2. 협력 디자인하기 / 3. 구현하기 의 단계를 거친다.

## 객체지향설계의 3가지 관점
- 개념 : 개념과 개념 간의 관계를 표현. 사용자 관점
- 명세 : 소프트웨어에 초점을 맞춤. 객체들이 협력 속에서 "무엇을" 할 지, 책임에 초점.
- 구현 : 우리에게 익숙함. "어떻게"에 초점을 맞춤

순서대로인 것이 아니고, 어떻게 보냐의 관점 차이. 그러니까 우리가 클래스를 볼 땐 저 3개가 다 섞여있음
- 클래스가 은유하는 "개념" : 도메인 관점(사용자 관점)
- 클래스의 "공용 인터페이스" : 명세 관점
- 클래스의 "속성, 메서드" : 구현 관점

우리가 앞서 협력 속의 객체가 어떤 역할을 할 수 있는가에 대해 초점을 맞춘 것은 명세 관점을 본 것

## 도메인 모델 ~ 최종 구현 맛보기
1. 도메인을 만든다<br>
구분되는 객체를 나열하고, 동일한 행동을 통해 타입을 파악하고, 타입 간의 관계를 파악한다.
2. 협력을 디자인하기<br>
1. 협력 찾기 : 커피 주문<br>
2. 협력을 시작하는 메시지 : 커피를 주문하라<br>
3. 이 메시지(=책임)을 처리하기 적합한 객체 선택 : 손님<br>

중간에 손님이 처리할 수 없는 행동은 다른 객체에게 위임(메뉴 정보 얻기, 커피 만들기)

4. 인터페이스 정하기<br>
메시지 이름, 인자 설정
3. 구현하기<br>
구현 도중 인터페이스가 변경되거나, 심지어는 식별하지 못한 인터페이스를 발견하기도 함.<br>
따라서 설계는 빠르게 하고 실제로 구현을 하면서 설계 내용을 구체화 해야한다.<br>
코드를 통한 피드백(이걸 방법론으로 만든게 TDD)

## 코드의 3가지 관점
코드는 객체지향설계의 3가지 관점을 모두 제공해야한다<br>
코드 = 제품 = 도메인

- 개념관점 : 클래스들이 도메인 모델을 반영함
- 명세관점 : 객체의 인터페이스<br>
수정하면 다른 객체에 영향을 주기 때문에 수정하기 어렵다.
- 구현관점 : 클래스의 내부 구현<br>
즉, 멤버 변수와 private 메소드. 이 친구들이 바뀐다고 공용 인터페이스가 바뀌면 안됨

실제 코드의 클래스 안에 이 3가지 관점을 다 포함하면서도 깔끔하게 보여줄 수 있어야 함.

도메인 개념을 참고하면, 코드 수정이 용이하다. 어떤 부분에 수정이 필요한지 명확히 보임.
안정적인 공용 인터페이스와 불안정한 내부 구현을 분리해야 한다.<br>
개념 - 명세 간의 구분은 크게 중요치 않지만. 명세 - 구현 간의 구분은 매우 중요하다.