다형성이 갖춰지면 객체지향 언어라고 할 수 있다.
대체가능성(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를 통해 부모를 확인하고 계속해서 위로 올라가며 메서드가 존재하는지 확인한다. 따라서 부모와 자식이 같은 함수를 가지고 있을 경우, 자식의 메서드가 호출되는 것이다.
자바스크립트에서 대체가능성 구현방식
const worker = class{
run(){ console.log("working")}
print(){ this.run() }
}
const hardworker = class{
run(){ console.log("hard working")}
}
const worker = new hardworker();
worker.print() // hard working
A instanceof B 일 경우,
객체 A의 proto를 확인하면, 원본의 constructor을 알 수 있으므로,
B의 constructor와 이가 같은지 확인한다. 같지 않을 경우에는 프로토타입 체이닝을 통해 부모의 constructor을 확인한다.
isolation of change: 변화에 대한 격리를 위해
SPR: 단일 책임 원칙
(이 코드를 고쳐야 하는 이유는 하나뿐인 것, 이를 지키지 못하면 shotgun surgery(산탄총 수술)이 일어난다.)
OCP: 개방 폐쇄 원칙: 새로운 수정사항들과 같은것은 extends나 implements를 하게 만들고, 기존에 있는 것들은 수정하지 않도록 만드는 것
Liskov Substitution. 리스코프 치환 원칙: 추상층의 정의가 너무 구체적이면 구상층의 구현에서 모순이 발생한다.
업캐스팅이 안전해야 하는데 추상클래스 구현시 너무 구체적일경우 구현이 오히려 힘들수있다.
ISP(Interface Segergation): 객체의 변화가 각각의 모듈과, 그 모듈의 인터페이스에만 영향이 가도록 해야한다.
추상화로 분리
DIP: 의존성 역전 법칙: 다운캐스팅금지
고차원의 모듈은 저차원의 모듈에 의존하면 안된다.
DI: 의존성 주입
IOC: 제어 역전
DRY(Don't Repeat Yourself): 중복 방지
Hollywood Principle: 의존성 부패방지(부모클래스는 서브클래스에 정의된 연산에 대한 호출을 할 수 있지만 그 반대방향은 일어나면 안 된다. 이렇게 어떤 대상에게 질의를 하게 되면 은닉, 캡슐화를 잊게 된다)
Law of demeter: 어떠한 객체에 대해 최소한의 지식만 알아야 함, 의존성의 부패를 막기 위해