인터페이스 머지 - ChoDragon9/posts GitHub Wiki

Spec

  • Spec 이름의 사용자형을 정의한다.
  • Descriptor와 Exporter로 이뤄지며, 역할은 데코레이터로 부여한다.
  • Descriptor는 항상 새로운 Spec를 반환한다.
  • Exporter는 Object, HTMLElement, String과 같은 데이터형으로 반환한다.

내부동작 예시

import {descriptor, exporter} from './decorator'

class Spec {
  #properties
  constructor (properties) {
    this.#properties = properties
  }
  @descriptor
  on (eventName, listener) {
    this.#properties[eventName] = listener
  }
  @exporter
  toJSON () {
    return Object.assign({}, this.#properties)
  }
}

export Spec

정적 펙토리 메서드

  • 정적 펙토리 메서드를 통한 생성 방법도 제공한다.
  • 싱글턴, 서브 타입 반환 등 활용성이 커지므로 객체 생성시 널리 사용되고 있는 방법(이펙티브 자바 책에 소개됨)
class Spec {
  #properties
  constructor (properties) {
    this.#properties = properties
  }
  static create (properties) {
    return new Spec(properties)
  }
}

const foo = new Spec()
const bar = Spec.create()

Element

  • Element는 HTMLElement를 정의한다.
  • 리턴값은 Spec을 반환한다.

내부동작 예시

export { div } from './div'
export { p } from './p'
export { text } from './text'

div.js

import Spec from '../Spec/index'
export const div = () => new Spec({nodeName: 'div'})

사용예제

import Spec from './Spec'
import { div, p, text } from './Element'

const spec = new Spec()
  .on('click', () => {})
  .className('table table-border')
const child = [
  div(),
  p(),
  text('Hello world')
]
const tag = div().spec(spec).children(...child)
const data = tag.toJSON()

spec

{
  spec: {
    className: 'table table-border',
    click () {}
  }
}

children

{
  children: [
    {nodeName: 'div'},
    {nodeName: 'p'},
    {nodeName: 'text', value: 'Hello World'}
  ]
}

data

{
  nodeName: 'div',
  children: [
    {nodeName: 'div'},
    {nodeName: 'p'},
    {nodeName: 'text', value: 'Hello World'}
  ],
  spec: {
    className: 'table table-border'
  }
}