LOGO
Published on

结构图插件系列:设计模式的应用

Authors
  • avatar
    Name
    梅亮
    Twitter

常用的设计模式有哪些?

常用的JavaScript设计模式包括工厂模式、单例模式、观察者模式、策略模式、装饰者模式等。我在结构图插件中用到了哪些呢?

单例模式

  • 单例模式:提示框(tips),文字超长提示、悬浮标题等。 以下是文字超长提示,关于单例的主要代码:
class TextTips {
  constructor() {
    if (!TextTips.instance) {
      this.initTipsGroup()
      TextTips.instance = this
    }
    return TextTips.instance
  }

  initTipsGroup() {
    // TODO
  }

  showTipsCard(params) {
    // TODO
  }

  hideTipsGroup() {
    // TODO
  }
}

策略模式

  • 策略模式:计算卡片坐标、计算卡片连线。 下面是计算卡片坐标的部分代码:
switch (layoutType) {
  // 平铺
  case 1:
    return childloadType(chartData)
  // 双列
  case 2:
    return childloadTypeDouble(chartData)
  // 单列
  case 3:
    return childloadTypeSingle(chartData)
  //纵向;
  case 4:
    return childloadTypeVertical(chartData)
}

代理模式

  • 代理模式:加载图片、卡片骨架占位。
class PaintCard {
  loadData() {}
  paint() {}
}
class CardProxy {
  constructor(paintCard) {
    this.paintCard = paintCard
  }
  paint() {
    // TODO
    ready().then(() => {
      this.paintCard.paint()
    })
  }
  ready() {
    // TODO
    return this.loadData()
  }
}

装饰者模式

  • 装饰者模式:各种用户自定义拦截规则、用户监听回调。 这个简单,直接用tsDecorator
class MainView {
  @beforePaint()
  paint() {
    // TODO
  }
}

组合模式

  • 组合模式:组装完整卡片等。
class PaintCard {
  constructor() {
    this.cardDom = []
  }
  add() {
    // TODO
  }
  addText() {
    // TODO
  }
  addRect() {
    // TODO
  }
  addImg() {
    // TODO
  }
  // TODO
  paint() {
    // TODO
  }
}

工厂模式:

  • 工厂模式:造各类显示元素
class TextDom{}

class RectDom{}

class SVGDomFactory{
    createSVGDom(tag){
        swich(tag){
            case 'text':
                // TODO
                return new TextDom();
            case 'rect':
                // TODO
                return new RectDom();
        }
    }
}

发布订阅

  • 发布订阅:大量用于事件监听和回调,使用户和插件交互主要方式。

export class ListenEvent {
  constructor() {
    // TODO
  }

  on(eventName: string, callBack: Myfunction) {
    // TODO
  }

  once(eventName: string, callBack: Myfunction) {
    // TODO
  }

  emit(eventName: string, params: any) {
    // TODO
  }

  remove(eventName: string) {
    // TODO
  }
}