V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
singworld
V2EX  ›  Java

程序版本控制问题,一套程序跑上百家医院如何做好版本控制

  •  
  •   singworld · 2019-07-21 19:56:21 +08:00 · 7968 次点击
    这是一个创建于 1978 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有一套医疗程序,同时给上百家医院使用 假设程序有 1,2,3,4 功能模块

    A 医院全部上了 B 医院上了 1,3,4 C 医院上了 1,2,3 但模块 3 有部分修改需求 D 医院第一年上了 1,2 模块对 1 有部分修改需求,次年又上了 3,4 模块又有部分修改需求

    想请教一下如何做好版本管理

    47 条回复    2019-08-31 01:16:16 +08:00
    fengjianxinghun
        1
    fengjianxinghun  
       2019-07-21 21:36:04 +08:00 via iPhone
    唯有复制 n 份
    unclemcz
        2
    unclemcz  
       2019-07-21 22:01:41 +08:00 via Android
    过来人的不成熟经验,医院业务系统(特指 his 这种强业务相关)搞同一版本就是作死,你很难找到两家业务流程完全一样的医院。和设备配套的系统则是越统一越好。
    shootsoft
        3
    shootsoft  
       2019-07-21 22:37:01 +08:00 via iPhone
    我建议你在每一个模块或者 feature 开发的时候加上一个开关,做好开关两个状态的测试,每个客户都有一个自己的配置文件,记录了每一个开关的状态。走正常的开发流程分支管理()就行。
    shootsoft
        4
    shootsoft  
       2019-07-21 22:38:28 +08:00 via iPhone
    手机有点问题括号里是比如 git-flow
    pagxir
        5
    pagxir  
       2019-07-21 22:41:38 +08:00 via Android
    这个其实不属于版本控制范畴,而是扩展性设计领域。
    reus
        6
    reus  
       2019-07-21 22:59:36 +08:00   ❤️ 1
    做成可配置的,然后做好测试,确保各种配置下,都能正确运行。
    复制 N 份?你有钱你可以试试,招人要钱,出医疗事故要赔钱,你自己掂量。
    Inside
        7
    Inside  
       2019-07-21 23:06:08 +08:00   ❤️ 1
    目前能想到的就是一条主干,拥有所有功能。
    然后按功能组合的不同,每个组合 release 一个分支。

    功能有修改的时候从某个 release 分支 fork 一个特性分支出来修改,然后 cherry-pick 到需要这个新改动的 release 分支去,如果改动是面向所有医院的,从主干 fork,然后合并到所有 release 分支。

    如此,至少做到了每个需求的代码只写了一次。

    当然,每个功能都有开关是必须的。
    zartouch
        8
    zartouch  
       2019-07-22 00:00:03 +08:00   ❤️ 3
    我们以前有个老系统就是这样的,因为代码写的太烂没人敢随便改,以至于当其中一个下游有改动的时候,就创建一个新的 release 版本,这样就算出事也不会影响到其他下游,到现在要维护 20 来个 release 版本。如果某个改动针对所有版本的话,因为要测试每个版本,每次上线测试 4 周,分批上线又要 2 周的时间,简直是项目管理的灾难。很多业务本来应该在这个系统修改,因为这个,只好在上下游系统做 workaround。 到我们今年接手,构架师 review 以后发现完全无法维护,决定重写。

    如果现在你们有人力还是慢慢重构系统,对不同的流做不同的配置,做好自动化测试,保证一个改动不对其他业务流产生影响。复杂的业务系统正确的做法是的好的领域驱动设计,加上完善的测试覆盖。千万别搞多个版本,现在省时间,过几年要命的。
    lights
        9
    lights  
       2019-07-22 00:07:09 +08:00
    代码层面的特性开关,Google 搜索「特性开关」有不少介绍的文章的
    Antidictator
        10
    Antidictator  
       2019-07-22 00:20:21 +08:00
    不能用权限控制吗?
    mywaiting
        11
    mywaiting  
       2019-07-22 00:32:20 +08:00   ❤️ 2
    挺有意思的一个问题,其实稍微大一些的服务政企的软件公司几乎都会遇到这样问题

    这远不只是代码版本的控制问题,我觉得这中间混合了软件工程中所有能遇到的问题

    开发、测试工程师就这么多,服务的企业 /商家 虽然类型大体一样(比如医疗行业 /能源行业),但每个企业甚至每个企业的子公司都会有自己乱七八糟的要求,这些要求不只是什么 UI 设计、流程,很多时候甚至要动到底层数据设计的,这时候问题就很多了

    我很想听听大神们对于这样的问题的看法
    zhuweiyou
        12
    zhuweiyou  
       2019-07-22 00:51:01 +08:00
    目前工作中也有类似的情况。
    我的做法就是一套代码 + N 套配置文件。

    复制多个项目维护会累死。
    anyele
        13
    anyele  
       2019-07-22 01:05:01 +08:00
    mark, 我能想到的就是一套代码, 做开关控制
    ericgui
        14
    ericgui  
       2019-07-22 01:13:03 +08:00 via Android
    @shootsoft 这个 idea 非常高明,微软就用这个思路
    TonyLiu2ca
        15
    TonyLiu2ca  
       2019-07-22 01:17:37 +08:00
    用 Cloud。如果是旧系统,弄个新的更新模块组 /机,并用 cloud 服务,将各个医院的配置文件集中管理
    tomczhen
        16
    tomczhen  
       2019-07-22 01:30:43 +08:00
    这个不是一个完全的技术问题,需要建立在良好的设计之上才能解决。事实是不论如何做版本管理,最终落地都会对开发人员有水平要求,而人员成本直接决定了版本管理方案最终能不能实行下去。对于很多小公司,由于人员流动高,管理水平有限,一份代码复制 N 份,一个客户一个压缩包是常态。

    当初我选择的方法是一个客户一个分支,然后可以合并的功能合并到主干,并做成可配置化,分支需要主干的功能时由对应负责的人去从主干合并到分支。数据库这边不使用所谓的保留字段,会造成同一个个字段不同客户有不同的业务意义,涉及到功能代码升级时无法平滑升级。

    实际实践中仍然一堆问题,主要是合并代码时对操作的人要求比较高,分支负责人通常都图方便,选择直接复制粘贴对应代码解决。当主干功能模块出现 bug 修复后,无法找到合并记录,还得人肉再对比修复。后面经过几次人员更新,又变回压缩包解决的方式了。

    后面我想明白了,在一定规模下,压缩包这种方式也确实可以有效降低人员要求和管理要求,也算是符合成本的解决方案。
    weiqk
        17
    weiqk  
       2019-07-22 02:53:18 +08:00
    git 我用的不多,但是我知道 svn 一个 tag 或分支都能解决你这个问题
    Humorce
        18
    Humorce  
       2019-07-22 04:09:33 +08:00
    二次开发,复制一份单独管理即可。

    只需要往主分支上把大量需求的功能加上,
    中标之后,二开的费用医院给得起。
    yuzo555
        19
    yuzo555  
       2019-07-22 04:12:13 +08:00
    除非你主版本做得 功能 /开关 都和齐全,否则别想“最新版本一统天下”
    msg7086
        20
    msg7086  
       2019-07-22 04:29:24 +08:00
    这样相当于为开源软件维护 mod 版,简单的做法是每个 mod 维护一个分支,每次主干升级以后 mod 分支 Rebase 然后做测试。主干破坏性升级后 mod 分支单独修复破坏的部分。
    saulshao
        21
    saulshao  
       2019-07-22 04:30:33 +08:00
    假设最极端的情况:你的功能有 100 个,但是每个功能都可能用到 100 个医院的不同特性,这个时候实际上就是 10000 个功能。
    这种规模的系统肯定是没法管理代码的。
    于是折中的方法就是提取出有共性的 80 个功能,这些功能针对 100 个医院使用同样的代码。而剩下的还是有 2000 个....
    但是功能的总数量下降到 2080 个,这是一个极大的进步了。
    再继续用上面的方法。使得功能下降到可以接受进行版本管理的程度,然后加入开关。但是如果你这套系统最终有 200 个开关,实际上也是一场噩梦。
    其实这套办法完全取决于你的系统有多少个功能.......我感觉开源软件其实就是这么干的。开源项目最大的优点是有几乎无限的开发资源...所以最后什么功能需要接受就成了一个最重要的事情。
    我也是搞类似的系统的,目前确实没啥好办法。
    0bject
        22
    0bject  
       2019-07-22 05:29:47 +08:00
    跟我 2 年前做过的项目一样。。。我是用的 #7 楼的做法
    jorneyr
        23
    jorneyr  
       2019-07-22 07:10:28 +08:00
    这个问题非常常见,很头疼,推荐代码用同一套,功能通过配置来启用和关闭,但是当遇到冲突的时候就需要多考虑下。
    flyz
        24
    flyz  
       2019-07-22 07:25:26 +08:00 via Android
    his 实施,只能说做开关就方便。

    医院的个性化流程是因为软件话语权不够强大导致的。

    100 个医院 100 个需求,但是梳理标准化流程,
    用标准化流程来作为主线,这部分尽量不改。
    弥补的确符合逻辑的功能做成开关。
    没一个开关要写清楚,这个开是干什么的关是干什么的即可。
    zjsxwc
        25
    zjsxwc  
       2019-07-22 07:54:31 +08:00 via Android
    每个功能都是插件,
    每个插件自己维护一个版本控制,
    每个客户提供一个插件配置文件
    wangxiaoaer
        26
    wangxiaoaer  
       2019-07-22 08:04:00 +08:00 via Android
    跟我说类似,但不是医院。

    我们是一套代码多套配置文件,优点是维护方便点,缺点是代码量庞大,构建耗时,安装包大,启动耗时,因为它相当多个项目的并集。
    est
        27
    est  
       2019-07-22 08:54:26 +08:00
    用班本控制来切换医院?灾难的设计啊。
    razertory
        28
    razertory  
       2019-07-22 10:55:23 +08:00
    直接上 github-flow 啊。一个医院 fork 一个 repository
    YoRolling
        29
    YoRolling  
       2019-07-22 11:52:15 +08:00
    子模块单独全部独立出来,然后 N 个医院 N 个仓库,git subModule 集成?
    annielong
        30
    annielong  
       2019-07-22 12:07:09 +08:00
    模块化,不过最怕某个模块的功能,必须修改核心代码,这时候核心代码可以加开关,但是如果这种模块多了也是灾难
    momocraft
        31
    momocraft  
       2019-07-22 12:12:27 +08:00
    插件化(框架化)
    写测试

    可能有帮助
    reus
        32
    reus  
       2019-07-22 12:29:56 +08:00
    要 fork 也是 fork 模块,不要 fork 分支。fork 模块就是将模块代码复制一份,放到同一个分支里。
    fork 模块,有重复代码也没关系,遇到需要修复的,也是修改同一个分支上的不同的文件,而不是多个分支。
    后面时间充裕了,可以慢慢合并重复的模块。这个需要一开始就有完善的测试,不然没法保证重构之后还能正常运作。
    当然,考虑到很多公司甚至测试都不写的,那可能就会选择 fork 分支,那就后果自负了。
    codehz
        33
    codehz  
       2019-07-22 12:35:25 +08:00
    之前微软不是有员工说 office 里有一大堆特性开关( Gate ),每次修改(加功能,修 bug )都要有开关可以控制。。。然后当然就是随之而来的一堆测试。。。
    qiyuey
        34
    qiyuey  
       2019-07-22 12:37:59 +08:00 via Android
    提供标准的能力和扩展点
    GODZZZZZ
        35
    GODZZZZZ  
       2019-07-22 13:42:23 +08:00
    感觉不是版本控制的问题,而是功能开关的问题
    还有就是可以保证每个医院的某个功能是相同的,而没有各自定制话的东西?
    jinhan13789991
        36
    jinhan13789991  
       2019-07-22 18:07:54 +08:00
    上面都说的很好,模块化。但是祖传代码怎么模块化呢? 工期在那里排着,只好 fork 分支然后改了。
    后面多个分支需求不同,代码差异化越来越严重。感觉就像一辆失去控制的火车,只能眼睁睁看它走向深渊
    janus77
        37
    janus77  
       2019-07-22 21:10:36 +08:00
    你们公司没那么大能力同时维护多个 oem 的多历史版本,那就开成多项目吧。
    xxxy
        38
    xxxy  
       2019-07-22 21:54:37 +08:00
    最近也遇到了类似的问题。目前是靠开多个 feature 分支启动多个服务来解决,等测试完成后再分支合并回主分支。至于楼主你的不存在最终统一的版本。要不就用七楼的方法,要不就每个医院建一个仓库,把基本功能分出来一个基本仓库,新增的差异部分写在各自的仓库。
    laozhoubuluo
        39
    laozhoubuluo  
       2019-07-22 23:18:44 +08:00
    上百家医院,完了还是您这种情况......

    这种问题十家八家的,模块化+模块控制可以解决。
    Base 框架所有医院共享一个,完了开发标准的 1-4 模块,互不冲突的功能都在标准模块实现,差别从配置文件解决。
    完了分支出来 3-C,1-D,3-D,4-D 解决模块间冲突。

    如果这个架构扩展成几十家医院,可以考虑按划分二级分支,差别从配置文件解决。
    比如北京市同一个医院对接医保系统的各个接口(医保卡认证、报销、查询其他医院用药记录)基本相同。
    比如北京统一挂号平台(网上预约号)在北京所有医院适用。
    比如北京京医通系统(挂号、缴费、检验单查询)在北京有接近二十家医院了。

    问题是如果是共性不多的上百家医院,如果又不能引导需求的话。
    我怕最后会出来几十个模块分支,继续 nightmare......
    laozhoubuluo
        40
    laozhoubuluo  
       2019-07-22 23:24:08 +08:00
    刚才有个小错误:
    比如北京市所有的医院对接北京市医保系统的各个接口(医保卡认证、报销、查询其他医院用药记录)基本相同。

    另外如果再不行,我觉得需要考虑微软 office 组的某些牛人了。牛到系统里做个大改动,一次改上千个文件完了系统还能 PASS 测试那种。
    chinvo
        41
    chinvo  
       2019-07-23 05:48:01 +08:00 via iPhone
    模块标准化,差异 mod 化,release patch 化
    yansideyu
        42
    yansideyu  
       2019-07-23 10:39:14 +08:00
    我们用的配置文件和砍需求,且国家有相关管理规范,砍需求的时候拿着鸡毛当令箭
    brust
        43
    brust  
       2019-07-25 13:45:39 +08:00
    一个医院一个分支
    singworld
        44
    singworld  
    OP
       2019-08-06 09:06:37 +08:00
    抱歉,没来得及及时回复,感谢楼上各位的建议
    目前我们的做法是 如果差异化比较小的部分就做代码层面的控制
    差异化比较大的医院就单独开一个新项目
    但维护的项目比较多,修改需求也比较多。已经在奔溃的边缘疯狂试探了
    singworld
        45
    singworld  
    OP
       2019-08-06 09:10:31 +08:00
    好在代码比较老旧的代码,准备重构了。
    singworld
        46
    singworld  
    OP
       2019-08-06 09:18:55 +08:00
    最悲剧的是手里还有多套老程序还在开发新程序,应用在多家医院,都面临这个情况
    charlie21
        47
    charlie21  
       2019-08-31 01:16:16 +08:00
    https://superphp.org/2019/516.html 谈到的 微软 开关 医院问题
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1012 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 20:39 · PVG 04:39 · LAX 12:39 · JFK 15:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.