diff --git "a/\354\235\264\355\230\204\355\235\254/AppendixA.md" "b/\354\235\264\355\230\204\355\235\254/AppendixA.md" new file mode 100644 index 0000000..f24acc2 --- /dev/null +++ "b/\354\235\264\355\230\204\355\235\254/AppendixA.md" @@ -0,0 +1,86 @@ +# 7장 + +## 요약 +1. 객체지향설계와 그 결과물인 코드는 3가지의 관점이 있다. 개념, 명세, 구현 +2. 도메인 모델 ~ 최종 구현까지는 1. 도메인 만들기 / 2. 협력 디자인하기 / 3. 구현하기 의 단계를 거친다. + +## 추상화 기법 +추상화 -> 도메인의 복잡성 단순화, 직관적 멘탈 모델 제작에 도움 + +종류 +- 분류/인스턴스화 +- 일반화/특수화 +- 집합/분해 + +분석, 설계, 구현 단계에서 일관성있게 적용가능 + +## 분류/인스턴스화 +객체를 분류하고 범주로 묶는 것 = 객체들의 집합에 공통 "개념"을 적용하는 것
+개념 = 유사한 객체들에게 공통적으로 적용되는 관념
+분류한다 = 범주라는 렌즈로 세상을 본다 = 객체에 개념을 적용한다 = 객체를 개념을 나타내는 집합의 요소로 포함시킨다. + +개념 = 공통 특성을 가진 객체의 집합
+개념과 타입은 아예 같은 말
+객체는 타입의 인스턴스임. + +객체, 곧 "타입"의 3가지 정의 +- 심볼 : 이름 +- 내연 : 의미 +- 외연 : 집합 + +분류의 종류 +- 단일 분류 : 객체가 한 시점에 한 타입을 가짐 +- 다중 분류 : 객체가 한 시점에 여러 타입을 가짐 + +프로그래밍 언어는 단일 분류만을 지원함.
+다중 분류는 다중 상속과는 다름.
+ +- 다중 상속 : 하나의 타입이 여러 슈퍼 타입을 가짐 +- 다중 분류 : 하나의 타입이 아님. 하나의 객체가 여러 타입을 가짐 + +- 동적 분류 : 객체의 타입이 바뀔 수 있음 +- 정적 분류 : 객체의 타입이 바뀔 수 없 + +프로그래밍 언어는 정적분류만을 지원함. + +클래스는 타입을 구현하는 방법 중 하나일 뿐.
+다른 방법으로는 추상 클래스, 인터페이스가 있음. + +## 일반화/특수화 +범주 즉 타입 간에는 계층이 있음. +상위 타입(슈퍼타입)을 하위 타입의 일반화라고 하고, +하위 타입(서브타입)을 상위 타입의 특수화라고 함. + +내연의 관점에서 서브타입이 되려면(100% 규칙), 슈퍼타입의 의미를 100% 가지고 있어야 함.
+외연의 관점에서 서브타입이 되려면(is-a), 슈퍼타입의 부분집합이어야 함. + +일반화가 되려면, 서브타입은 슈퍼타입에 구조적/행위적 순응을 해야함
+순응 = 대체 가능성
+구조적 순응은 "속성, 연관관계"가 대체가능해야 한다는 것
+행위적 순응은 "행위"가 대체가능해야 한다는 것 + +상속은 서브타이핑, 서브클래싱으로 구분됨. +- 서브타이핑 : 대체가능함. 설계유연성이 목적. =인터페이스 상속 +- 서브클래싱 : 대체불가능함. 코드 재사용이 목적. =구현 상속 + +상속이라고 무조건 대체 가능성을 보장하는 서브타이핑이 아니고,
+내부적으로 그냥 코드 재사용을 위해 쓴 것일 수도 있음 + +가상함수로만 넘겨주면 서브타이핑인 셈이고,
+구현된 함수를 넘겨주면 그 함수를 재사용하기 위한 서브클래싱일 수 있음 + +상속 계층에서 메시지를 이해하는 법 "위임"
+내가 처리하지 못하는 메시지는 부모에게 넘긴다. + +## 집합/분해 +복잡성은 계층의 형태로 표현가능하다.
+중간계층이 있으면 더 쉽게 이해할 수 있다. + +집합 = 부분으로부터 전체를 만들어내는 것 +분해 = 그 반대 + +중간계층이 여러 개를 하나로 표현해줌 = 추상화 +중간계층 아래는 굳이 볼 필요 없음 = 캡슐화 + +- 합성관계 : 부분과 전체 관계. 전체가 사라지면 부분도 사라짐(생명주기) +- 연관관계 : 부분과 전체가 아닌 그냥 관계. 한쪽이 사라져도, 다른 한쪽이 사라지지 않음(생명주기) \ No newline at end of file diff --git "a/\354\235\264\355\230\204\355\235\254/Chapter6.md" "b/\354\235\264\355\230\204\355\235\254/Chapter6.md" new file mode 100644 index 0000000..ed812d6 --- /dev/null +++ "b/\354\235\264\355\230\204\355\235\254/Chapter6.md" @@ -0,0 +1,80 @@ +# 6장 + +## 요약 +1. 설계는 기능과 구조 2가지를 모두 고려하는 것이다. +2. 객체지향설계가 은유할 객체들은 도메인 모델에서, 객체지향설계가 분배할 책임은 유스케이스에서 나온다. + +## 기능보다 구조가 안정적이다 +길을 묻는 것과 지도의 예시 + +기능은 해결 지향적이고, 구조는 문제 지향적이다. + +기능보다 구조가 더 바뀔 가능성이 적다. 따라서 구조를 바탕으로 모델을 만들어야 변경 수요가 적다. + +설계는 기능(사용자에게 해줄 것, 충분조건)과 구조(제품의 형태, 필요조건)를 적절히 조화시키는 것. + +착각하지 말아야 할 점은, 우리는 미래를 예측할 수 없기 때문에 설계 시에 어떤 변화를 예측하기 보다는, +변화를 적게 할 수 있도록 여지를 남기는 방향이 더 좋다.
+=> 이 여지를 남기는 방법이 바로 구조를 이용하는 것 + +## 객체지향 세계 설계를 위한 2가지 재료 +객체지향 세계 설계를 위한 2가지 재료는 기능과 구조이다. + +이 재료를 얻는 방법 +- 기능 => 유스케이스 모델링 +- 구조 => 도메인 모델 + +### 도메인 모델링 +도메인 = 사용자가 프로그램을 사용하는 분야
+모델 = 필요한 정보만 선택해 단순화 한 것
+도메인 모델 = 소프트웨어가 사용되는 분야 내의 개념이나 관계 등을 단순화한 것 + +도메인 모델은 멘탈 모델의 일종
+멘탈모델이란 사람의 마음 속에 가지고 있는 관계/규칙/제약 모델(본능적으로 구축하는 모델이라고 봐도 될 듯) + +멘탈모델은 +- 사용자 모델(사용자 관점) +- 디자인 모델(설계 관점) +- 시스템 이미지(통합) +이렇게 3가지로 구성된다. + +설계자는 디자인 모델과 사용자 모델을 통해 구축한 시스템 이미지(=제품)을 통해서 사용자의 피드백을 받을 수 있음. + +좋은 제품은 사용자 모델을 전부 반영한 제품이고, 소프트웨어로 치면 좋은 코드는 사용자 모델을 전부 반영한 코드이다. + +도메인 모델의 3가지 종류를 모델링할 수 있는 유일한 패러다임 = 객체지향
+심지어 3가지 종류가 다 비슷해질 수 있음 = 연결완전성 + +소프트웨어는 현실의 은유이다. 여기서 말하는 현실, 즉 은유의 대상이 바로 도메인 모델이다.
+즉 현실 그 자체가 아닌, 사람들이 현실을 보고 만들어낸 멘탈 모델을 옮겨야 하는 것. + +도메인 모델은 안정적인 구조를 제공한다.
+왜냐하면 사람들은 도메인의 본질적인 것을 잘 알고 있고 이를 통해 멘탈 모델을 만든 것이기 떄문 +- 비즈니스가 없어지거나 개편되지 않는 한 안정적으로 유지됨 +- 개념 간의 관계는 비즈니스 규칙을 기반으로 하기 때문에 비즈니스 정책이 크게 변경되지 않는 한 안정적으로 유지됨 + +### 유스케이스 모델링 +기능적 요구사항 = 시스템이 사용자에게 제공해야할 기능의 목록을 나열한 것 + +유스 케이스 모델링 = 사용자가 특정한 '목표'를 가지고 시스템과 '상호작용'하는 흐름을 텍스트로 묘사한 것
+사용자의 목표라는 관점을 통해서 그냥 나열된 기능들을 하나로 묶어줌 = 연관된 기능의 집합을 만들 수 있음
+한 번의 상호작용을 시나리오라고 함. 시나리오를 묶어주는 걸로도 볼 수 있음 + +- 다이어그램이 아니고 텍스트 형태임 +- 인터페이스와 같이 자주 변하는 내용은 포함하지 않음 +- 내부 설계에 대한 내용도 포함하지 않음 +- 설계에 대한 힌트만 얻을 수 있을 뿐 일반적인 규칙(명사는 클래스 동사는 메소드 어쩌구..)은 얻을 수 없음 + +### 도메인 모델, 유스케이스, 책임 주도 설계의 관계 +도메인 모델은 책임 주도 설계가 은유할 객체의 모델을 제시하고,
+유스케이스는 책임 주도 설계가 분배해야 하는 책임을 제시한다. + +내가 책임 주도 설계 부분을 읽으면서, 협력 속에서 적합한 객체에게 적합한 책임을 분배해야한다는 말을 보고
+아니 그럼 객체 식별은 어케함??이라는 의문을 가졌었는데 이게 말끔히 해소된 것 같다. + +기능적인 요구사항이 변경되면, 책임과 일부 객체 간 대응 관계만 변한다. +객체지향의 큰 장점은 바로, 도메인 모델링 기법 = 도메인을 코드로 옮기는 방법이라는 점이다.
+도메인 모델에서 코드로의 변환가능성을 연결완전성이라고 하고
+코드에서 도메인 모델로의 변환 가능성을 가역성이라고 한다. + +결과적으로, 코드와 도메인 모델은 분리되지 않는다. \ No newline at end of file diff --git "a/\354\235\264\355\230\204\355\235\254/Chapter7.md" "b/\354\235\264\355\230\204\355\235\254/Chapter7.md" new file mode 100644 index 0000000..0aa1107 --- /dev/null +++ "b/\354\235\264\355\230\204\355\235\254/Chapter7.md" @@ -0,0 +1,50 @@ +# 7장 + +## 요약 +1. 객체지향설계와 그 결과물인 코드는 3가지의 관점이 있다. 개념, 명세, 구현 +2. 도메인 모델 ~ 최종 구현까지는 1. 도메인 만들기 / 2. 협력 디자인하기 / 3. 구현하기 의 단계를 거친다. + +## 객체지향설계의 3가지 관점 +- 개념 : 개념과 개념 간의 관계를 표현. 사용자 관점 +- 명세 : 소프트웨어에 초점을 맞춤. 객체들이 협력 속에서 "무엇을" 할 지, 책임에 초점. +- 구현 : 우리에게 익숙함. "어떻게"에 초점을 맞춤 + +순서대로인 것이 아니고, 어떻게 보냐의 관점 차이. 그러니까 우리가 클래스를 볼 땐 저 3개가 다 섞여있음 +- 클래스가 은유하는 "개념" : 도메인 관점(사용자 관점) +- 클래스의 "공용 인터페이스" : 명세 관점 +- 클래스의 "속성, 메서드" : 구현 관점 + +우리가 앞서 협력 속의 객체가 어떤 역할을 할 수 있는가에 대해 초점을 맞춘 것은 명세 관점을 본 것 + +## 도메인 모델 ~ 최종 구현 맛보기 +1. 도메인을 만든다
+구분되는 객체를 나열하고, 동일한 행동을 통해 타입을 파악하고, 타입 간의 관계를 파악한다. +2. 협력을 디자인하기
+ 1. 협력 찾기 : 커피 주문
+ 2. 협력을 시작하는 메시지 : 커피를 주문하라
+ 3. 이 메시지(=책임)을 처리하기 적합한 객체 선택 : 손님
+ + 중간에 손님이 처리할 수 없는 행동은 다른 객체에게 위임(메뉴 정보 얻기, 커피 만들기) + + 4. 인터페이스 정하기
+ 메시지 이름, 인자 설정 +3. 구현하기
+ 구현 도중 인터페이스가 변경되거나, 심지어는 식별하지 못한 인터페이스를 발견하기도 함.
+ 따라서 설계는 빠르게 하고 실제로 구현을 하면서 설계 내용을 구체화 해야한다.
+ 코드를 통한 피드백(이걸 방법론으로 만든게 TDD) + +## 코드의 3가지 관점 +코드는 객체지향설계의 3가지 관점을 모두 제공해야한다
+코드 = 제품 = 도메인 + +- 개념관점 : 클래스들이 도메인 모델을 반영함 +- 명세관점 : 객체의 인터페이스
+수정하면 다른 객체에 영향을 주기 때문에 수정하기 어렵다. +- 구현관점 : 클래스의 내부 구현
+즉, 멤버 변수와 private 메소드. 이 친구들이 바뀐다고 공용 인터페이스가 바뀌면 안됨 + +실제 코드의 클래스 안에 이 3가지 관점을 다 포함하면서도 깔끔하게 보여줄 수 있어야 함. + +도메인 개념을 참고하면, 코드 수정이 용이하다. 어떤 부분에 수정이 필요한지 명확히 보임. +안정적인 공용 인터페이스와 불안정한 내부 구현을 분리해야 한다.
+개념 - 명세 간의 구분은 크게 중요치 않지만. 명세 - 구현 간의 구분은 매우 중요하다. \ No newline at end of file