【修养篇】【思维篇】【管理篇】团队组织与架构演进方法论

前言

  团队组织相关概念集合

用户故事

  敏捷开发常提的词,把系统的需求开发比喻为一个大世界的历史书,但历史是由每个章节组成的,每一次用户提需求,我们都要把需求闭环,这个把用户的需求闭环的过程称为用户故事,一般一个用户故事由1到2个人就可以开发完成。属于增量开发模式,缺点是只有局部,没有大局观,优点比较适合快速迭代的业务节奏,快速交付业务价值。

Sprint迭代


  团队开发组织的一种周期迭代模式,比较适合业务团队,不太适合技术团队,一般分为两周14天作为一个周期,周期内活动包括:技术方案设计、方案评审、方案设计、测试、上线;同时产品和开发、测试都应该按照这个周期一同协作活动。

  产品需求池:业务产品化的需求池,由产品维护,产品Leader带团队进行评审;

  技术需求池:系统需求有可能是产品需求、也可能是技术需求,技术需求池由技术小Leader维护。

  同时注意,需求池应该以用户故事来组织,但求需求闭环和逻辑严谨。

使能故事

  使能故事是相对于用户故事而言,使系统能力得以提升,属于大局观的系统概念,所以为了保证系统概念一致性不建议经常换掌控系统大局的人,也不用没有大局观的人。

  敏捷团队需要完成用户事故外拿出部分经历开发使能故事。主要内容有:

  • 挖掘用户需求的本质,注意是挖掘,不同与获取用户的需求;
  • 优化甚至重构现有代码,提高代码质量;
  • 调整系统架构,支持未来可见的变化;
  • 下沉算法和技术,构建业务中台,业务通用框架等;

  使能故事计较忌让没有技术追求的同学做,如果只是领导下命令,同学为了使能而使能,大概率失败。

两顶帽子

  在设计使能故事的时候,(或者小部分用户故事),可以分配设计者和实现者部分事件去使用两顶帽子戏法,一般是在你需要添加新功能的时候,发现代码和既往的抽象无法很好的支持该功能,而做的事情:

  第一顶是:把当前的软件编写目的为重构,改良软件结构,不改变软件功能,目的是为了代码和结构更加容易的添加新功能。

  第二顶是:为当前软件添加新功能,这个时候应该是第一顶帽子发挥作用后,使得添加新功能变得非常容易。

技术中台

  技术沉淀每个公司应该有自己定制化的可复用技术,当业务沉淀发现有适合公司的轮子可以服用的时候,可以沉淀一种技术中台,其实也可以用外部开源技术,然后组织一部分同学专门做技术中台;技术沉淀大概率上是由使能故事的结果。

  约定优于配置:技术中台必然要走的路,复用技术后,必然要做倒置依赖,所以各个业务系统需要遵循中台约定,牺牲个性的路线,才能达到提效目的。

  DevOps和GitOps大部分要求完善的技术中台和基础设施平台,小公司慎用。

测试驱动

  注重测试,尤其在核心系统上,注重单元测试和建立集成测试、回归测试;互联网平台要建立完善的系统边界对每个业务场景用例进行自动化集成测试。成本较大,并且适合有重构和演进追求的系统,普通CURD和打算堆人力系统不会认为测试有用。

结对编程

  对比结对编程,结对讨论方案,review代码更好,确实,两个人会互相质疑使得模型更加好,这也是以模型和方案都是可以设计为适应性模型和适应性方案为前提的。但三个人以上只会加大沟通成本。结对也希望两个人能够在软件的沟通上能一致,水平要相当才行。

极限编程

  文档其实是会说谎的,最会说谎的是PPT,其中极限编程其实围绕的核心是主张完全不使用(多余的)设计文档,而是让代码解析自己;因为实际运行的代码不会说谎,但是其他文档则不然;

分析文档

  分析的目的,是为了理解问题。

  有时候,我们做项目,需要需要写一份文档,而这份文档或许不会有其他人看,而是给自己看或者思考用的,这个过程其实更多是做分析工作,而这种分析工作大概率会和我们后面的实现脱离,但这不是重点,重点是我们在这个过程中对问题更加深入的理解了;

沟通成本

  组织人员的工作安排,最好在同一个闭环的逻辑子域中,让更少的人参与,1个人最佳;人和人之间的合作逻辑交互越高,沟通成本越大,效率越低。所以工作安排不要把一项工作定位20人/日后,就认为存在2个人只需10日就可以搞定这样的神话故事。

概念一致性

  愿景—〉战略—〉战术—〉方案—〉落地,不同架构师有不同职责,软件系统架构师是规划师,要注意:

  • 技术团队子域架构Leader的规划是细到模块和对象级别
  • 技术团队子域架构Leader必须要参与核心代码设计与开发,至少要了解代码,控制腐烂程度
  • 别做分任务和催进度的传话人
  • 别做只设计业务PPT而概念的人,而不关注过落地的人,对自己系统的模块做啥都不了解的请尽快离职。

  最后注意,一场手术,只能有一个操刀医生,医生要对手术结果负责——择:人月神话

统一规范

  规范可以作为概念一致性的辅助工具,也是减少沟通成本的一种工具,例如:代码规范、日志规范、通用框架规范、通用请求返回结构体规范等;

模型选择

  解决一个问题的模型可以有很多中,上级和下级也可能有不同的模型,而模型本身没有对错之分,关键在于哪个模型更加适用;同时为了鼓励下属的自主能动性,建议在模型差别不大的情况下,让实现的人进行自主选择;

产研分离

  平台与业务分离,在写业务系统的时候,通常有大部分逻辑可以归纳为平台逻辑,特别对于中台系统的产生特别重要,有了平台后,平台的研发可以兼容赋能到产品研发是衡量产研分离成功的标准;

架构即组件

  不要相信架构师是不需要写代码,只做高层策略的人,架构师一定是在一线的程序员。所以架构的设计,无论是跨城市、跨机房、跨服务器、跨进程、跨对象,归根都到,都是设计组件和组件之间的依赖关系。只有组件才是实现策略工作的实际所在,所以架构师,就是懂得如何设计组件和组件之间的关系的人。

本质复杂度和偶然复杂度

  要解决一个问题,如果改问题本身的定义是复杂的,那么这个称之为问题本身的复杂度。如果我们做的解决方案引入的,我们称之为偶然复杂度,后者是可通过设计优化可控的,前者是无法减少的。团队管理不好,开发人员方案不好,等等都可能会引入偶然复杂度。

  • 状态机和状态同步模型是一个很好的例子,例如物流订单,在初始化、创单、支付、取消可以是状态机器,但分拣、配送、妥投这是状态同步,其中问题空间变了,所以要抓住本质,用状态机解决状态同步模型,就是增加了偶然复杂度。

界限上下文和组织

  最好,一个团队负责一个界限上下文,这不意味不可以按需要调度。

  在重构和思考一个界限上下文的时候,如果发现出另一个界限上下文,那么可以独立出一个新的上下文,也就是界限上下文是可以在演进中产生的。

  • 一个例子,物流单和各个作业单就无法在一个上下文中,他们各自有各自的上下文。
  • 履约和库存跟踪分离就是一个界限上下文的体现
  • 一个长用例,需要多个上下文协作的时候,不同上下文解析这个用例是不一样的

战术编程与战略编程 

  战术编程即战术龙卷风,战略编程通常要求一个人有系统的思维和视野,慢慢把系统变成整体偏好的系统。战略编程应该有两个维度:

  • 一个是水平维度,在多个子域和系统之间,或者系统内部,在概念上保持一致性;
  • 一个是时间维度,一个系统在时间上的发展,应该具有一致性,体现在演进理念要一致,所以最好不要频繁换人;

中间件的意义

  之前说过,计算机没有什么问题不能通过加一层解决,而中间件也是很重要的一层,不同中间件提供的层服务能力是不同的,可以分离很大一部分异常和性能问题,封装和提供了可靠的服务语义(保证消费、保证成功)

  • 中间件很像TCP服务的IP层、网络层等,但它提供的是水平的层级能力
  • 架构上,可以做业务上的中间件,例如阿里的“精卫”就是一个很好的例子,例如我的履约ERP库存系统。

通用语言

  通用语言是重要的,主要表现为在用例中,表示出通用语言,在实体中表现出通用语言,在值对象,实体中等等;

  • 通用语言的重要性在于它主导者代码的设计;
  • 用例组织要用通用语言解析起步骤;

无法衡量的激励政策

  一个大公司想要战略一致是很难的。 高层领导者关心的是整个集体的利弊和走向,不用干实事,所以他只能依赖委托。并给委托方一定的激励政策。

  • 如果体系复杂,衡量标准困难,被委托方会想尽办法获取激励奖励,然后制造难以衡量的PPT门面。
  • 软件体系建设是一个难衡量价值的建设,所以容易滋生蛀团蛀虫。

建模本质分析法

  • 从领域空间角度看待要完成的事情是什么?
    • 计算机是否是领域空间的角色之一
  • 从解答空间角度看待要完成的事情是什么?
    • 系统边界在哪里
    • 与外界的输入输出是否闭环
  • 以闭环为起始点,看是完全模拟问题,还是协作互动问题

卫语句

  使用卫语句是为了减少理解成本。

工程驱动产品理念

  • 开始应该是以产品为主,按产品和业务需求来设计系统。直到产品和业务需求无法提高规模的时候。
  • 后期一定的成熟期后,产品开始进入无增长空间,以好的系统驱动产品,如果系统不够优秀则无法驱动产品设计。

知识体驱动设计

  如何指导你的设计,在DDD看来是领域知识驱动,但是比起DDD更提升一层的理念,应该是知识体驱动设计。

  • 第一件事,对领域进行充分的理解,其实统一语言就是为了帮助软件开发软件去理解知识的,本质上是一种软件开发者获取知识的交流手段
  • 第二件事,是对问题本质的思考,对问题本质的思考,意味你需要看透你所面临的软件开发是什么问题。
    • 如果你只是一个外包仔,那么你不需要思考太多不能归你掌控的事情,能if就if;
    • 问题是否具备逻辑特性,具有逻辑性,可以推理的特点,是掌控万变不离其宗的核心,也是本质复杂度的核心;
    • 问题本身具有多少长期内不容易变特性,多少抽象特性,是否有去建立模型的价值;
  • 第三件事,是最痛苦的阶段,根据你对问题的思考,建立一个知识体系,用该体系去解析问题,这一步也称之为建模,但比起软件建模,更多的是思维上的建模,在内心/大脑成立一套模型出来;
  • 第四件事,代码实现,其实内存和代码都是丑陋的,他们都受技术影响,因此DDD的domain其实也不纯粹,只要知识体系是完备的,这个时候,各种具体的开发工作,都应该围绕着这个知识体系去进行,考虑下面几点可以让你更加清晰明白什么是知识体系驱动设计。
    • 如何用GO和JS去实现DDD呢?
    • 能不能理解线程和过程的区别呢?他们在知识体系中起到什么作用呢?
  • 第四件事,通常第三件事可能伴随模型突破,但是软件大部分是长期迭代才能沉淀出越加稳定和完善的知识体系,所以问题生命周期越长,就需要继续演进知识体系。

生命周期

要重视生命周期的管理,特别是单例对象,例如线程池对象的优雅下线

 

posted @ 2021-08-21 21:51  饭小胖  阅读(400)  评论(0编辑  收藏  举报