→ 본능적으로 이해하기 쉽고 예측 가능한 수준으로 현실을 분해하고 단순화해야한다.
→ 불필요한 부분을 제거하기 때문에, 현실에 존재하는 복잡성을 극복할 수 있다.
→ 필요한 부분, 현실에서 분석 혹은 파악하려는 것의 맹점을 더 두드러지게 할 수 있다.
✔️ 첫번째 차원 : 구체적인 사물들 간의 공통점은 취하고 차이점은 버리는 일반화
✔️ 두번째 차원 : 중요한 부분을 강조하기 위해 불필요한 세부사항을 제거
어떤 공간에 서로 다른 국가의 사람 100명과 서로 다른 종류의 50마리의 개가 있다고 생각해보자.
이들은 모두 다른 150개의 객체이다. 하지만 사람 그리고 개, 이 두가지 그룹으로 나누어 단순화할 수 있다.
→ 세상에는 수 많은 특징들을 가진 여러 객체들이 있지만, 이런 복잡성을 그룹 단순화를 통해 효과적으로 감소시킬 수 있다.
✔️ 객체가 어떤 개념으로 나뉜 그룹의 일원이 될 때, 그 객체는 해당 개념의 인스턴스
개념을 가르키는 간략한 이름이나 명칭
ex) 인간, 개, 고양이
개념의 완전한 정의. 내연의 의미를 이용해 객체가 개념에 속하는지에 대한 여부를 확인가능
개념을 이루는 집합의 공통적인 특징이라고 생각하면 편할 것
ex) 인간은 팔다리가 두개씩 있고, 눈이 두개고, 코가 하나고 등등
개념에 속하는 모든 객체에 집합 (set)
ex) 철수, 영희, Tom, Alice 등등
→ 객체에 특정한 개념을 적용하는 작업
→ 특정 객체를 특정 개념의 집합에 포함시키거나 포함시키지 않는 작업
❗️타입은 컴퓨터 공학자들의 '개념'과 동일한 용어로 심볼, 내연, 외연을 이용해 서술 가능
실제 데이터가 저장되는 메모리를 들여다보면, 타입이라는 것은 존재하지 않고 0과 1이라는 숫자뿐이다.
이렇게 0과 1만을 보고는 데이터의 종류를 구분할 수 없기 때문에, 데이터를 타입별로 분리하고 타입시스템이라는 것이 생겨나기 시작했다
→ 메모리 속의 0과 1에 대해 수행 가능한 작업과 불가능한 작업을 구분함으로써 데이터의 오용 방지
→ 특정 데이터가 4칙연산이 가능하면 숫자형, 두 문자를 붙혀 문자열을 만들 수 있으면 문자형
→ 개발자는 숫자 타입 데이터가 메모리에 어떻게 저장되는지 몰라도, 어떤 연산자를 사용해야하는지만 알면 숫자 타입 데이터를 사용하는데 지장이 없다
객체 지향에서 객체는 일종의 데이터처럼 사용된다. 수많은 객체들을 타입에 따라 분류하고 타입에 이름을 붙히는 것은 새로운 데이터타입을 선언하는 것이다.
→ 객체지향에서의 핵심은 '객체가 협력을 위해 어떤 행동을 하는지'이기 때문에, 객체 구분의 핵심도 역시 객체의 책임 또는 행동이다.
→ 객체가 행동을 효과적으로 수행하기만 한다면 내부 표현 방식은 어떻게되어도 상관없다.
→ 여기서 동일한 행동은 동일한 책임을 의미하고 동일한 책임은 동일한 메세지를 수신하고 처리할 수 있다는 것.
→ 동일한 메세지를 처리하는 방법은 객체마다 다를 수 있다. (다형성)
💡 동일한 메세지를 서로 다른 방식으로 처리하기 위해서는 결국 동일한 메시지를 수신할 수 있어야하는데, 이는 동일한 타입에 속해야 가능하다.
→ 훌륭한 객체지향 설계는 행동만을 외부에 공개하고 데이터는 내부에 감춰야한다 (캡슐화).
✔️ 객체가 외부에 제공해야하는 행동(책임)을 생각 : 책임 주도 설계 (Responsibility-Driven Design)
MapleStory라는 게임에서 암석으로 이루어져있고 혼자서 걸어다닐 수 있 '골렘'이라는 몬스터를 생각해보자. 우리는 이를 암석이라는 타입으로 분류할 수 있다. 그런데 직접 걸어다니지 못하는 '자연의 암석'도 게임속에 존재한다. 이 역시도 암석이라는 타입으로 분류할 수 있다. 둘의 외향은 암석으로 비슷하지만 '골렘'은 자연의 암석과 비교해서 혼자 걸어다닐 수 있기 때문에, 암석몬스터라는 타입으로 분류하는 것이 옳다. 이 관계를 아래와 같이 표현할 수 있다.
_ _ _ _ _ _ _ _ _ _ _ 암석 _ _ _ _ _ _ _ _ _ _ _ _
| |
| _ _ _ _ _ _ _ _ _ _ 암석몬스터 _ |
| | | |
| | | |
| | _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |
**** _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
→ 암석 몬스터의 외연집합은 암석의 외연집합의 부분집합으로 표현할 수 있다.
→ 암석은 암석몬스터를 포괄하는 일반적인 개념, 암석몬스터는 암석보다 특화된 행동을 하는 특수한 개념이다.
→ 일반화와 특수화는 상대적인 것이므로, 반드시 일반적인 것과 상대적인 것이 필요하다
→ 일반적인 타입은 자신이 포함하는 타입들이 가진 모든 행동들 중에 일부 공통적인 행동만을 가지는 타입
→ 특수적인 타입은 자신을 포함하는 타입의 일반적인 행동에 더해 자신만의 특수한 행동도 가지는 타입
→ 특수한 행동을 추가적으로 가지는 특수 타입은 일반 타입에 비해 외연 집합의 원소수가 적다
→ 일반적인 행동만을 가지는 일반 타입은 특수 타입에 비해 외연 집합의 원소수가 많다.
→ 서브타입은 슈퍼타입의 행위를 할 수 있기 때문에, 슈퍼타입을 대체할 수 있어야한다.
추상화의 두번째 차원은 중요한 부분을 강조하기 위해 불필요한 세부사항을 제거하는 것이었다.
누군가가 '자연의 암석'과 같이 있는 '골렘'을 보았을 때, "뭐야 암석들 밖에 없네?"라고 걸을 수 있다는 골렘의 특수 행동을 무시하고 골렘을 일반화 시킬 수 있다.
'공병주'라는 객체는 햄버거를 먹고(+3kg) 굶음(-2kg)에 따라 몸무게라는 '상태'가 동적으로 변한다. 햄버거를 먹고 굶음에 따라 발생할 수 있는 모든 몸무게들을 생각하는 것이 아니라, '공병주'라는 객체의 '행동은 햄버거를 먹고, 굶는 것이 있고 몸무게라는 객체는 임의의 값을 가질수 있다'라고 시간에 독립적인 정적인 모습으로 공병주를 생각할 수 있다.
✔️ 시간에 따라 객체가 어떻게 변하고 어떻게 행동하는지를 포착하는 모델
✔️ 객체가 가질 수 있는 모든 상태와 모든 행동을 시간에 독립적으로 표현하고 변화의 가능성에만 집중하는 모델
✔️동적으로 변하는 객체의 상태가 아닌 객체가 속한 타입의 정적인 모습을 표현
✔️ 객체지향 프로그래밍을 하는 것은 시스템을 정적인 관점에서 접근하는 것
✔️ 프로그램을 실행하거나 디버깅하여 객체의 상태변경을 추적하는 것은 동적인 관점
✔️ 타입은 객체를 분류하기 위한 개념이고, 클래스는 타입을 구현하기 위한 메커니즘이다.