DSL 领域模型架构:学会它,让你不在做牛马!

106 阅读3分钟

1. 工作痛点

在前端开发中,你是否有过常年在工作中一直为 CRUD 重复性的工作而烦恼呢,CRUD 体力活占用大量的时间,多套系统交付间产生了大量的重复性工作,开发工作也是偏向页面性的开发。能力不仅得不到成长,更是消耗了大量的心力。

2. 如何解决

  • 避免相似的功能重复性的开发;
    • 沉淀 80% 的重复性工作,支持可配置。
    • 同时支持 20% 的客制化开发。
  • 更多参与系统架构开发和迭代上的工作;
    • 落地系统平台持续集成。
  • 支持多套系统建设,无需重复开发相同功能;
    • 平台支持多套建设,且系统功能可服用。
  • 技术及综合能力全面提升;
    • 全栈开发,引入 nodejs,devOps 等流程。

通过上述的解决方案,我们可以很好的解决我们的痛点,这时候就需要引出我们的主角 —— DSL 领域模型架构

3. DSL 领域模型架构设计

DSL 概念我就不赘述了,直接上的设计思路:

graph TD
DSL模板配置 --> 模板页面 --> 电商系统
模板页面 --> OA系统
模板页面 --> 课程系统
模板页面 --> ...系统

通过模板页的继承,可以很好的解决了多套系统建设,无需重复开发相同功能的问题。

DSL模板配置是通过 json-schema 进行编写。schema 驱动页面结构:

  • 根据 schema 生成系统:侧边栏、顶部栏、路由;
  • 根据 schema 生成系统页面;
  • 根据 schema 生成页面组件:搜索框、表格列表、各类组件(弹窗、表单、抽屉等);
  • 根据 schema 生成业务 API;
  • 根据 schema 生成建表SQL语句;

schema 设计配置如下

export default {
  mode: "dashboard", // 模板类型,不同模板类型对应不一样的数据结构
  name: '', // 名称
  homePage: '', // 首页(项目配置)
  // 头部菜单
  menu: [
    {
      key: "", // 菜单唯一描述
      name: "", // 菜单名称
      menuType: "", // 枚举值, group / module

      // 当 menuType == group 时,可填
      subMenu: [
        {
          // 可递归 menuItem
        },
        // ...
      ],

      // 当 menuType == module 时,可填
      moduleType: "", // 枚举值: iframe / custom / schema / sider

      // moduleType == iframe 时 
      iframeConfig: {
        path: "", // iframe 路径
      },
      // moduleType == custom 时
      customConfig: {
        path: "", // 自定义路由路径
      },
      
      // moduleType == sider 时
      siderConfig: {
        menu: [
          {
            // 可递归 menuItem(除 moduleType === sider)
          },
        ],
      },

      // moduleType == schema 时
      schemaConfig: {
        api: '', // 数据源 API (遵循 RESTFUL 规范)
        schema: { // 板块数据结构
          type: 'object',
          properties: {
            key: {
              ...schema, // 标准 schema 配置
              type: '', // 字段类型
              label: '', // 字段中文名
              // 字段在 table 中的相关配置
              tableOption: {
                ...elTableColumnConfig, // 标准 el-table-column 配置
                toFixed: 0, // 保留小数点后几位
                visiable: true, // 默认为 true
              },
              searchOption: {
                ...elComponentConfig, // 标准 element component 配置
                comType: '', // 配置控件类型 text / select
                default: '' , // 默认值

                // comType === 'select'
                enumList: [], // 下拉框可选项 

                // comType === 'dynamic-select'
                api: '', // 请求 url

                
              },
              comOption: {},
              apiOption: {},
              dbOption: {}
            },
            // ...
          },
          // ...
        },
        tableConfig: {
          headerButtons: [{
            label: '', // 按钮中文
            eventKey: '', // 按钮事件名
            eventOption: {
              // 当 eventKey === 'remove'
              params: {
                // paramKey => 参数的键值
                // rowValueKey => 表格中的参数值的 key 或 固定值 (当格式为 schema:tableKey 时,到 table 中找到相应的字段)
                paramKey: rowValueKey
              }
            }, // 按钮具体配置
            ...elButtonConfig, // 标准 el-button 配置

          }],
          rowButtons: [{
            label: '', // 按钮中文名
            eventKey: '', // 按钮事件名
            eventOption: '', // 按钮具体配置
            ...elButtonConfig, // 标准 el-button 配置
          }]
        }, // table 相关配置
        searchConfig: {}, // search-bar 相关配置
        comConfig: {}, // 模块组件
        apiConfig: {}, // API 相关配置
        dbConfig: {}, // 数据库 相关配置
      },
    },
    // ...
  ],
};

4. 结论

通过学习和掌握DSL领域模型架构,开发者可以显著提高开发效率,减少重复劳动,避免成为“牛马”。DSL的设计理念、优越性和实现方法为我们提供了一种全新的开发思路和方法,值得我们在实际工作中加以应用和推广。

学习资源:抖音-哲玄前端 大全栈实践课