코드스피츠 86 객체지향 자바스크립트 - 4회차 part1 (step 33)

KHW·2021년 3월 29일
1

js-study

목록 보기
20/39
post-custom-banner

객체지향프로그램

덩어리 진 것을 분리하는 과정

애자일(agile)

변화에 기민하면서도 효율적으로 대응하는 다양한 개발 방법론
개발해 나가면서 필요한 것들을 피드백을 바탕으로 주도적으로 개발
일정기간 협력과 피드백의 반복

권한 <=> 책임

권한이 있으면 책임이 있고 책임이 있으면 권한이 있어야한다.

인터페이스 분리 원칙 (ISP)

viewModel이 heavy한 상태이므로 이를 권한과 책임에따라 분리해야한다.

const ViewModel = class extends ViewModelListener {
  static get = data => new ViewModel(data)
  static #subjects = new Set
  static #inited = false
  static notify (vm) {
    this.#subjects.add(vm)
    if (this.#inited) return
    this.#inited = true
    const f = () => {
      this.#subjects.forEach(vm => {
        if (vm.#isUpdated.size) {
          vm.notify()
          vm.#isUpdated.clear()
        }
      })
      requestAnimationFrame(f)
    }
    requestAnimationFrame(f)
  }
  static descriptor = (vm, category, k, v) => ({
    enumerable: true,
    get: () => v,
    set (newV) {
      v = newV
      vm.#isUpdated.add(new ViewModelValue(vm.subKey, category, k, v))
    }
  })

  static define = (vm, category, obj) => (
    Object.defineProperties(
      obj,
      Object.entries(obj)
            .reduce((r, [k, v]) => (r[k] = ViewModel.descriptor(vm, category, k, v), r), {})
    )
  )

  subKey = ''; parent = null
  styles = {}; attributes = {}; properties = {}; events = {}
  #isUpdated = new Set; #listeners = new Set

  constructor(data, _ = type(data, 'object')) {
    super();
    Object.entries(data).forEach(([k, v]) => {
      if('styles,attributes,properties'.includes(k)) {
        if(!v || typeof v != 'object') throw `invalid object k: ${k}, v:${v}`
        this[k] = ViewModel.define(this, k, v)
      } else {
        Object.defineProperty(this, k, ViewModel.descriptor(this, '', k, v))
        if (v instanceof ViewModel) {
          v.parent = this
          v.subKey = k
          v.addListener(this)
        }
      }
    })
    ViewModel.notify(this)
    Object.seal(this)
  }

  viewmodelUpdated (updated) { updated.forEach(v => this.#isUpdated.add(v)) }
  addListener (v, _ = type(v, ViewModelListener)) { this.#listeners.add(v) }
  removeListener (v, _ = type(v, ViewModelListener)) { this.#listeners.delete(v) }
  notify () { this.#listeners.forEach(v => v.viewmodelUpdated(this.#isUpdated)) }
}

섬세한 권한조정

javascript는 기본적으로 public이다 => 코드조작이 쉬워져 문제발생이 높다.

transaction

일정코드가 한번(transaction)에 일어나기 위해 함수를 사용한다.

profile
나의 하루를 가능한 기억하고 즐기고 후회하지말자
post-custom-banner

0개의 댓글