디자인패턴과 뷰패턴 2회차 - ChoDragon9/posts GitHub Wiki

Gof 디자인 패턴은 하드웨어 리소스가 부족한 시절에 만들어서 연산(CPU)을 많이 사용하는 방향으로 만들어 졌다. 하지만 현재는 리소스가 여유롭기 때문에 메모리(RAM)을 많이 사용하여 속도를 향상하는 방향으로 개발하게 됬다.

객체지향개발의 학술적 조건

  1. 대체가능성
  2. 내적일관성
const Parent = class {}
const Child = class extends Parent {}
const a = new Child()
console.log(a instanceof Parent);

Child는 Parent를 대체할 수 있다는 것을 의미하며, 자바스크립트에서는 프로토타입 체이닝으로 구현하였다.

  1. 내적동질성 태생을 그대로 유지할려는 성격
const Parent = class {
  wrap() { this.action() }
  action() { console.log("Parent") }
}
const Child = class extends Parent {
  action() { console.log("Child") }
}
const a = new Child();
a.wrap(); // output: Child

알고리즘 분화 시 객체지향에서 선택할 수 있는 두가지 방법

데이터가 변경되었을 때와 로직이 변경되었을 때는 해결하는 방법

상속 위임

속도와 효율이 좋아짐

내부계약관계로 추상층에서 공통 요소를 해결하고 상태를 공유할 수 있음

class Parent {
  constructor() {
    this._base = 'http://web.com';
  }
  load(path) {
    this._load();
  }
  _load() {
    throw 'override!'
  }
}
class Child1 extends Parent {
  _load() {}
}
class Child2 extends Parent {
  _load() {}
}

탬플릿 패턴을 통해 각각 행동이 기술된 사용자형을 통해 구현한다.

소유 위임

메모리를 많이 쓰게 됨

외부계약관계로 각각이 독립적인 문제를 해결하며 메시지를 주고 받는 것으로 문제를 해결함

class Parent {
  constructor() {
    this._base = 'http://web.com';
  }
  load(path) {
    this._parser(path);
  }
  set parser(v){
    this._parser = v;
  }
}
const parent = new Parent();
parent.parser = loadImage;
parent.load();

parent.parser = loadMarkdown;
parent.load();

전략 패턴을 통해 사용자형의 인스턴스 하나로 알고리즘만 변경해서 사용가능하다. 하지만 숙련도가 부족하면 추적하기 힘들다.

class Parent {
  constructor() {
    this._base = 'http://web.com';
  }
  load(path) {
    this._parser[0](path, ...this.parent[1]);
  }
  setParser(f, ...args){
    this._parser = [f, arg];
  }
}
const parent = new Parent();
parent.setParser(loadImage, ['png', 'jpeg']);
parent.load();

parent.setParser(loadMarkdown, ['title', 'description']);
parent.load();

커맨드 패턴 invoker를 통해 실행기 등록자를 통해 등록한 명령어를 실행한다.

라우팅 테이블

분기분을 삭제할 수 없기 때문에 우회적인 방법을 사용한다. 경우의 수 만큼은 라우팅 테이블을 만들어 필요할 때 키를 통해 접근한다.

const Loader = class {
  constructor(id, repo) {
    this._git = new Github(id, repo);
    this._router = new Map();
  }
  add(ext, f, ...arg){
    ext.split(',').forEach(v => this._router.set(v, [f, ...arg]));
  }
  load(v){
    const ext = v.split('.').pop();
    if(!this._router.has(ext)) return;
    this._git.setParser(...this._router.get(ext));
    this._git.load(v);
  }
}
const loader = new Loader('yongkucho', 'ChoDragon9');

loader.add('jpg,png,gif', img, el('#a'));
loader.add('md', md, el('#b'));

loader.load('xx.jpg');
loader.load('xx.md');

으로 구현을 했던 사항을 발생가능한 경우의 으로 기술한다. 값으로 기술함으로써 각각을 격리하여 견고하게 개발할 수 있다. 역할을 분담하여 각각에게 할당하여 행동을 추가할 수 있다.

패턴을 부르는 패턴

실행시점으로 패턴을 만들게 되면 런타임에 정상적으로 동작해야 하는 것이 보장되어야 함으로 불안정하다. 그 불안정을 해결하기 위해 팩토리, 빌더, 퍼사드 패턴을 사용하여 런타임에 안전성있게 동작이 되도록 한다. 행동패턴을 사용함으로써 안전성 보장을 위해 생성/구조패턴이 따라가는 것이다.