将业务拆分多个服务并实现数据继承

174 阅读2分钟

背景

在大型和复杂的业务中,我们会将逻辑拆分成多个服务用来处理不同的业务场景。子服务需要使用同一份数据或公共方法等,用JS继承是比较好的方式。

JS实现继承的方式有很多种,原型链继承、构造函数继承,组合继承,原型式继承,寄生式继承,寄生组合式继承,ES6 Class 语法。

下面介绍一下使用“原型式继承”实现业务拆分不同子服务实现。

原型式继承Demo:

通过 Object.create 方法创建一个新的对象,该对象的原型指向父对象。

const parent = {
    name: 'parent',
    sayHello: function() {
        console.log('Hello from ' + this.name);
    }
};

const child = Object.create(parent);
child.name = 'child';
child.sayHello(); // 输出:Hello from child

1. 定义function

首先,我们需要定义一个 function 用于接收数据

// previewService.js
import AllocationService from './allocation'
import AdSubmitService from './ad-submit'
import BatchEditService from './batch-edit'
import HelperService from './helper'

export default function (
  bluePrint,
  bluePrintConfig,
  bluePrintService,
  getCurAccountListFn,
  campaignSnInfo,
  adSnInfo,
  creativeSnInfo
) {
  
 // ...

}

2. 实现原型父对象

实现一个自定义函数,定义原型父对象并添加新数据

function helperParent(
  bluePrint,
  bluePrintConfig,
  bluePrintService,
  getCurAccountListFn,
  campaignSnInfo,
  adSnInfo,
  creativeSnInfo
) {
  // 1. 定义原型父对象
  const parent = {
    bluePrint,
    bluePrintConfig,
    bluePrintService,
    getCurAccountListFn,
    campaignSnInfo,
    adSnInfo,
    creativeSnInfo
  }
  // 2.通过 `Object.create` 方法创建一个新的对象,该对象的原型指向父对象。
  const helper = Object.create(parent)

  for (let key in HelperService) {
    helper[key] = HelperService[key]
  }
  // 3. 添加新公共数据
  parent.curModuleVars = helper.defineCurModuleVars()

  return parent
}

3. 添加子服务对象原型指向原型父对象

现在,我们可以在 添加任意的子服务了

最后renturn 所有子服务

export default function(//...//) {
    // 获取原型对象
   const helpParent = helperParent(//...//)
   // 添加子服务
   const allocation = Object.create(helpParent)
      for (let key in AllocationService) {
       allocation[key] = AllocationService[key]
   }
 
  return Object.assign(parent, {allocation} )
}

这样AllocationService中可以使用helpParent中的所有数据。

// allocation.js
const allocation = {
 initMediaAccountList(adResult) {
     // 使用原型数据
     if(this.bluePrint){
         // ...
     }
 }
}
export default allocation

使用

// 1. 传入数据
this.curPreviewService = new PreviewService(
    this.myBluePrint,
    this.bluePrintConfig,
    this.bluePrintService,
    this.getCurAccountListFn,
    this.campaignSnInfo,
    this.adSnInfo,
    this.creativeSnInfo
)
// 2. 使用子服务
const accountList = this.curPreviewService.allocation.initMediaAccountList(adResult)

完整代码

import AllocationService from './allocation'
import AdSubmitService from './ad-submit'
import BatchEditService from './batch-edit'
import HelperService from './helper'

function helperParent(
  bluePrint,
  bluePrintConfig,
  bluePrintService,
  getCurAccountListFn,
  campaignSnInfo,
  adSnInfo,
  creativeSnInfo
) {
  //
  const parent = {
    bluePrint,
    bluePrintConfig,
    bluePrintService,
    getCurAccountListFn,
    campaignSnInfo,
    adSnInfo,
    creativeSnInfo
  }
  const helper = Object.create(parent)

  for (let key in HelperService) {
    helper[key] = HelperService[key]
  }
  parent.curModuleVars = helper.defineCurModuleVars()

  return parent
}

export default function (
  bluePrint,
  bluePrintConfig,
  bluePrintService,
  getCurAccountListFn,
  campaignSnInfo,
  adSnInfo,
  creativeSnInfo
) {
  // 所有子类共享的变量(数据唯一出口)
  const parent = helperParent(
    bluePrint,
    bluePrintConfig,
    bluePrintService,
    getCurAccountListFn,
    campaignSnInfo,
    adSnInfo,
    creativeSnInfo
  )

  let serviceObject = {
    allocation: AllocationService,
    adSubmit: AdSubmitService,
    batchEdit: BatchEditService
  }
  let service = {}
  for (let name in serviceObject) {
    service[name] = Object.create(parent)
    for (let key in serviceObject[name]) {
      service[name][key] = serviceObject[name][key]
    }
  }

  // 子服务组合
  const serviceGroup = {
    // 批量操作回调
    handleBatchEditOk({ data, editConfig, tbody, tbodyIds }) {
      const AllocationService = service.allocation
      service.batchEdit.handleChangeCallback({
        data,
        editConfig,
        AllocationService,
        tbody,
        tbodyIds
      })
    }
  }

  return Object.assign(parent, { ...service }, { ...serviceGroup })
}

结论

通过上述示例,实现不同子服务共用数据能力

ps:历史代码升级,入参数据可以简化。