다형성이 갖춰지면 객체지향 언어라고 할 수 있다.
대체가능성(substitution): 확장된 객체는 원본으로 대체 가능
내적일관성(internal identy): 어때한 경우에도 태어났을 때의 원본 클래스를 유지하려고하는 속성(생성 시점의 타입이 내부에 일관성 있게 참조됨)
worker hardworker class(function)
proto --> hardworker prototype (constructor(함수의 프로토타입이므로 가지게 됨, 자기 자신을 가리키고 있음), proto(객체이므로 얘도 가짐), 클래스의 메소드들)
즉,
class HardWorker extends Worker
const worker = new HardWorker();
에서 worker은 proto를 가지는데, 이는 자신의 원본인 hardworker의 프로토타입을 가리킨다. hardworker의 프로토타입 또한 객체이므로 proto를 가지고, 함수(function)의 프로토타입이므로 constructor을 가진다. 이는 자기 자신을 가리키고 있다. HardWorker은 Worker을 상속받았으므로, proto는 Worker의 프로토타입을 가리킨다.
따라서 프로토타입 체이닝이란, 해당 객체의 proto를 확인해서 원본의 프로토타입을 확인하고, 그 원본의 proto를 확인하는 방식을 반복하며 진행된다. 이를 통해 constructor로 직접 원본을 확인하거나, 원본이 가진 메서드를 확인해 대체가능성과 내적일관성을 구현할 수 있다.
먼저 그 객체의 메서드들에서 존재하는지 확인하고, 그 다음 proto를 통해 부모를 확인하고 계속해서 위로 올라가며 메서드가 존재하는지 확인한다. 따라서 부모와 자식이 같은 함수를 가지고 있을 경우, 자식의 메서드가 호출되는 것이다.
A instanceof B
일 경우, 객체 A의 proto를 확인하면, 원본의 constructor을 알 수 있으므로, B의 constructor와 이가 같은지 확인한다. 같지 않을 경우에는 프로토타입 체이닝을 통해 부모의 constructor을 확인한다.
변화에 대한 격리를 위해
고차원의 모듈은 저차원의 모듈에 의존하면 안된다. 이 두 모듈 모두 추상화된 것에 의존해야 한다.????
DI: 의존성 주입
IOC: 제어 역전
DRY(Don't Repeat Yourself): 중복 방지
Hollywood Principle: 의존성 부패방지(부모클래스는 서브클래스에 정의된 연산에 대한 호출을 할 수 있지만 그 반대방향은 일어나면 안 된다. 이렇게 어떤 대상에게 질의를 하게 되면 은닉, 캡슐화를 잊게 된다)
Law of demeter: 어떠한 객체에 대해 최소한의 지식만 알아야 함, 의존성의 부패를 막기 위해
단일 책임 원칙을 준수하는 객체에게 그 이상의 업무를 부여하면
다른 객체에게 의뢰하는 것 = 다른 객체에게 메세지를 보내는 것
오퍼레이션과 메소드를 분리해서 상황에 따라 원하는 메소드를 호출하기 위해 추상클래스나 인터페이스를 상속시킨다.(OCP)
의존성이 있으면 의존되는 관계에 있는 객체들의 영향을 그대로 받는다. => 격리성을 높여야
너무 의존성이 없으면 만능 객체가 태어나게 됨. 너무 의존성이 크면 한 객체가 수정되거나 추가되면 다른 객체들이 전부 영향을 가지게 된다. 따라서 적당한 의존성을 가져야 한다.
객체의 생명 주기 전체에 걸친 의존성
각 오퍼레이션 실행 시 임시적인 의존성
-> 의존: 오퍼레이션 실행 시에만 연결이 되고, 메서드 호출이 되면 의존성이 생기고 호출이 끝나면 의존성이 사라지는 약한 의존성을 가진다.
연관에서 의존으로 바꾸기 위해서는 상태를 저장해놓는 방식을 포기해야 한다. 그러면 함수형 아니냐, 따라서 쉽게 바꾸지 못함
어떠한 경우에도 다운캐스팅은 금지하고 다형성 사용하는 것. DIP와 OCP는 깊은 연관을 가지고 있다. 부모쪽에 의존성을 가지면, 새로운 자식이 추가되어도 기존의 코드는 수정되지 않아 OCP가 이뤄진다고 볼 수 있기 때문이다.