夜雨聆风学习资料网

ARTICLE · 1089396

企业软件为什么不能像装 App 一样安装?

企业软件为什么不能像装 App 一样安装?

企业软件真正应该复用的,不只是代码,而是已经被结构化、验证过的业务经验。

适合阅读:CTO / 企业 IT 负责人 / SaaS 创业者 / 架构师 / 企业软件开发者

一、一个部门做完,另一个部门为什么还要重新做一遍?

一家企业的采购部门,花了 6 个月,做了一套采购系统。系统终于上线,项目团队松了一口气。

过了一年,人力资源部门找上门:我们需要一个 HR 系统。于是 IT 部门,又从头开始了——建表、建 API、做权限、做表单、做列表、做流程、做审批、做日志、做部署。

再过一年,客服部门说:我们需要一个 Helpdesk。又重新开始。项目管理部门说:我们需要一个项目管理系统。又,重新开始。

于是,这家企业内部,出现了一个很奇怪的现象:

系统越来越多,但企业的软件生产能力,并没有明显地积累起来。

这就像一个奇怪的悖论:一家车厂,不会每造一辆车,就重新发明一次发动机。可企业做软件,却常常是每做一个新系统,就重新设计一遍数据模型、重新写一遍权限、重新做一遍审批、重新搭一遍 UI、重新配一遍部署。

因为这里藏着一个值得每个 CTO 想一想的问题:公司过去明明做过这么多系统,为什么下一次做一个类似的系统,还是要从数据库设计开始?

二、为什么企业软件,特别容易重复造轮子?

企业软件,表面上看千差万别:采购、合同、HR、Helpdesk、项目、合规、CRM……名字都不一样,业务也各不相同。

但如果你把它们一个个拆开,会发现一件事——绝大多数企业系统,其实是由一批高度相似的基础结构组成的:

  数据:  Object(对象) · Field(字段) · Relation(关系) · Status(状态)

  界面:  List(列表) · Form(表单) · Detail(详情) · Dashboard(仪表盘)

  权限:  Role(角色) · Permission(权限) · 记录访问 · 字段访问

  流程:  提交 · 审批 · 驳回 · 升级 · 完成

  服务:  评论 · 附件 · 审计 · 通知

真正不同的,往往只是——这些基础结构,如何被组合成某一家企业自己的业务。

所以,问题不该是采购系统和 HR 系统,是不是完全一样——当然不一样。真正该问的问题是:为什么每一个新系统,都必须从这些基础积木,重新开始搭一遍?

所以:

企业软件缺的,可能不是代码复用,而是应用结构的复用。

三、代码复用,解决不了从零开始的问题

讲到这,有人会说:复用这件事,工程界不是早有一堆办法了吗?

这话没错。npm 包、Java 库、SDK、框架、组件库、微服务、内部脚手架——这些,确实都在解决复用问题,而且解决得很好。我不否认它们的价值。

但奇怪的是,即便有了这么多复用手段,企业软件里那些东西,还是常常要重新做一遍:Customer、Vendor、Employee、Contract、Approval、Ticket、Project……为什么?

因为企业真正想复用的,不只是一个函数,不只是一个 React 组件,甚至不只是一个微服务。企业真正想复用的,是——一整个已经成型的业务应用结构。

比如一个采购应用,它可能已经包含了这样一整套东西:

  Vendor(供应商) · Purchase Request(采购申请)

  Purchase Order(采购订单) · Approval Flow(审批流)

  Approval Status(审批状态) · Permission Set(权限集)

  Views(视图) · Actions(动作) · Audit(审计) · Attachments(附件)

这一整套东西合在一起,才是一个真正有价值的起点。而 npm 包、组件库这些,给你的,是一颗颗螺丝、一块块零件。

过去的软件复用,大多是在复用零件;而企业应用真正需要复用的,是已经组装好的业务结构。

四、那复制上一套代码,为什么也不是答案?

企业里最容易想到的复用,是直接复制。既然采购系统做过了,B 部门要用,那把上一套代码拷一份,改一改,不就行了?

看起来很合理,但这条路,很快就会出问题。

一开始,A 系统叫 procurement-v1;B 系统,是 procurement 的一份拷贝,然后改;C 又拷贝 B;D 又拷贝 C。于是 A、B、C、D,开始各自独立演进。几年之后,一个熟悉的画面出现了:

  A 系统: 有一个 bug

  B 系统: 这个 bug 已经修了

  C 系统: 这个 bug 没修

  D 系统: 又自己加了一套特殊逻辑

于是,复用最后变成了 Copy & Paste。你得到的,不是一个可以长期复用的软件资产,而是一堆越走越远、谁也对不齐的代码分叉。

这里,其实藏着三个很容易被混为一谈、但完全不同的概念:

  Copy(复制):

     复制的,是当前这一刻的状态。拷完就各走各的,断了联系。

  Fork(派生):

     复制的,是一个「有边界、可以继续独立演进」的应用起点。

  Package(应用包):

     则更进一步——这个应用,可以被安装、被版本化、

     被分发、被升级、被继续扩展。

Copy 得到的是一份死的拷贝;而 Fork 和 Package,得到的,是一个活的、有身份、有版本、能继续长下去的东西。这个区别,是后面一切的基础。

五、企业真正需要的,是可安装的业务应用

我们先来看一个简单的问题。

为什么装一个开发工具,一句 `npm install` 就好了?为什么装一个数据库,一句 `docker pull` 就好了?可为什么装一个业务应用,却往往要经历——立项 + 需求分析 + 开发 + 测试 + 部署,几个月之后,才终于拿到一个能用的系统?

当然,复杂的企业系统,不可能像手机 App 那样,完全一键安装——这一点必须诚实承认。但我们可以退一步想:

为什么企业软件,不能至少拥有一个已经成型的起点?

想象一下,如果一个采购应用,装好之后,里面已经有了供应商、采购申请、采购订单、审批、状态、视图、权限;一个合同应用,装好之后,已经有了合同、签约方、合同状态、审批、附件、到期提醒、审计;一个 Helpdesk,装好之后,已经有了工单、客户、优先级、SLA、指派、状态、视图……

那么,企业做的事,就不再是从零开发一个系统,而是从一个已经成型的业务应用开始,改它。这两件事的成本结构,是完全不一样的。

而这,正好帮我们厘清一个常见的误解:很多人以为,模板(Template)就是一个 Demo——给你看看长什么样。这个理解,太浅了。一个真正有价值的企业软件模板,里面应该已经包含了业务对象、字段、关系、视图、动作、工作流、权限、基础数据、应用导航、完整的业务结构。

Template 不是给你看一下它长什么样,而是给你一个可以继续生产下去的业务系统。

如果把复用分层,你会看得更清楚:第一层,复用一个函数(代码片段);第二层,复用一个能力(组件 / 模块);第三层,复用一个完整的业务结构(应用模板)。而企业软件真正长期缺少的,恰恰是第三层。

六、从开发一个系统,到从一个系统开始

如果企业不应该每次都从零开始,那么它需要什么样的应用复用机制?我们看看 ObjectOS 的 Templates 提供的一种具体实践(以其当前官方文档为准),但重点不是罗列功能,而是看它回答了什么问题。

据当前官方文档,ObjectOS 把 Template 定义为可 Fork 的起点包(Forkable starter packages)。当前的官方模板目录,包括合同、采购、合规、工单、HR、项目、待办、内容等几类。我们不逐个念名字,挑几个看看它们作为起点意味着什么。

采购(Procurement)。据当前文档,它已经包含采购业务需要的基础结构——供应商、采购订单、三方匹配(3-way match)、审批链等。重点不是它有多少个字段,而是:企业不需要,再从一个空白项目开始。

合同(Contracts)。它可以作为一个合同管理应用的起点,而不是让你自己从头再建一遍 Contract、Party、Approval、Expiry……。

工单(Helpdesk)。据当前文档,它已经有了工单、SLA、以及 AI 辅助(co-pilot)等相关结构,企业可以从这个起点继续扩展。

HR。它提供了通讯录(Directory)、组织架构图(Org chart)、休假(Time-off)、以及以人为中心的应用结构。

模板的价值,不在于替企业省几个小时写代码。它真正的价值是——把一种已经被验证过的业务结构,变成下一次可以继续使用的软件资产。

七、真正重要的,是Fork,而不只是Install

据当前文档,ObjectOS 的 Templates,大致有两条路径。

第一条:Install(安装)。在 Marketplace(应用市场)里找到模板,直接安装,得到一个可以运行的应用。它解决的,是我不想从零开发,我需要一个已经准备好的起点。

第二条:Fork(派生)。如果企业需要更深度的定制,可以把模板,fork 成自己的一份 TypeScript 代码库,然后在上面继续:修改、测试、提交、构建、发布。到这一步,这家企业,就不再只是用了一个模板,而是——从一个已有的业务应用,继续演进成自己的产品。

再往后,据当前文档,改得足够成熟之后,还可以重新构建、发布成自己的 Package / Marketplace 项。而 ObjectOS / ObjectStack 的 Package,本身就是一个可以被组织、被版本化、被安装、被分享的应用单元。

Install 和 Fork,对应的,其实是两种完全不同的需求:Install 是我需要一个已经准备好的应用;Fork 是我需要把这个应用,变成我自己的产品、我自己的业务系统。想清楚这个区别,你就不会把这件事,停留在Marketplace = 应用商店这种浅层理解上了。

Marketplace 解决分发,Fork 解决演进。

八、当企业开始拥有自己的软件资产库

最后我们来看一家大型企业,过去做过采购系统、合同系统、Helpdesk、HR、项目管理。以前,这些项目做完之后,会发生什么?代码,散落在各个 Git 仓库;文档,散落在 Confluence;数据库,各自独立;而最宝贵的经验,散落在几个开发人员的脑子里。于是,下一个项目,还是重新开始。

但如果,这些系统,都可以沉淀成可安装、可 Fork、可版本化的业务 Package,那么企业真正积累下来的,就不再只是代码,而是——业务应用资产。

  Company Procurement Template  v1.0

  Company Contract Template     v2.1

  Company Helpdesk Template     v1.4

这时候,下一家子公司需要采购系统,做的事,不再是重新立项,而是:Fork 一份公司的采购模板,然后根据自己的业务,调整字段、权限、流程、组织、视图。企业软件的开发方式,开始出现一种新的积累路径:

  过去: 项目 → 代码 → 项目结束(经验随之流失)

  现在: 项目 → Package → Template → Fork → 新项目

回到开头那个场景。A 部门已经做过采购系统,B 部门又提出同样的需求。

传统的第一反应,是:那就重新立项吧。而一个更成熟的反应,应该是先问一句:我们,有没有一个采购模板?如果有,就 Install;如果需要改,就 Fork;如果改得足够成熟,就再把它变成一个新的 Template。于是,一次开发,变成了一次沉淀;一次沉淀,支撑了多次复用;多次复用,又推动了持续演进。

企业软件真正应该复用的,不只是代码,而是已经被组织、验证和结构化过的业务经验。

说到底,如果每做一个系统,都必须从一个空白项目开始,那么企业真正积累的,可能只是越来越多的代码,而不是越来越强的软件生产能力。而 ObjectOS Templates 想解决的,恰恰不是少写几行代码,而是——让一个已经成型的企业应用,可以成为下一个应用的起点。

——本文以 ObjectStack / ObjectOS 开源项目与产品为分析对象。涉及 ObjectOS Templates 的部分,以其当前官方文档为准:当前官方模板包括 todo、contracts、procurement、compliance、helpdesk、content、hr、project 等,文档将 Template 定义为「可 Fork 的起点包」(Forkable starter packages),支持通过 Marketplace 安装(Install)、通过 CLI fork 成 TypeScript 代码库继续修改 / 测试 / 演进(Fork)、并可重新构建发布为自己的 Package / Marketplace 项(Publish);具体能力与命名以最新官方文档为准。

ObjectStack(开放技术基础) · ObjectOS(企业业务操作系统)

相关学习资料