如何组织工作坊

背景和目标

项目为了进入一个产品,需要整个系统降低资源消耗。而因为原来系统并没有相应的应对方案,现在选择的方案是尽量使用原来的系统服务,进行资源降低以及组件裁剪。事实上并不是进行简单的裁剪就能完成交付的,还需要为了剪裁组件调整部分功能,并且同时还需要补充该产品价值需求。
现在交付管道遇到一些问题,表现为故障多、交付带宽不足、交付承诺有达不成、开发团队人力无法支撑需求等现象。 还有就是需要达到一个非常极致的低消耗,可能以各组件进行简单的缩减内存无法达成目的(之前产品一直注意进行资源消耗,所以可以通过简单方法可以缩减的资源并不大)。为了使这个产品的开发能够消除这些问题,做好产品交付,部门领导组织了这次工作坊。

流程

  1. 首先是破冰,相邻两个人交流一下最近感觉开心的事。事实证明,这个操作确实对于后面讨论具有一定破冰效果
  2. 前期问题收集信息的澄清,主要包含:产品规划、项目管理、质量现状、架构挑战等。
  3. 前期问卷调查收集问题,以及现场分组:产品定位与交付策略组、架构方案组、项目管理组、开发测试组、与用户产品协调组。每组确定组长之后,其他人根据喜好选择自己的组,但是每组人数需要协调到基本一致。
  4. 每组头脑风暴列出该组主题的问题,并为这些问题排定优先级(组内可以适当控制一下问题数量)
  5. 每组进行问题展示,接受提问
  6. 小组讨论,寻找根因。可以采用 5why法,我参与的组是头脑风暴加讨论进行寻找根因的。
  7. 每组进行根因展示,接受提问
  8. 小组针对每个根因,讨论输出解决方案。
  9. 然后进入世界咖啡环节:组长不动,小组其他成员轮转到其他感兴趣的专题桌。主持需要协调一下各组人数
    1. 组长进行解决方案介绍
    2. 过程中,过来的人挑战组长介绍的解决方案
    3. 组长进行解决方案调整
  10. 进行2轮转移,期间组长要跟每个解决方案的干系人进行确认,方案是否可以落地
  11. 每组进行方案展示,并形成AP并确定干系人

人员选择

  • 项目规划人员
  • 架构团队
  • 项目管理团队
  • 交付团队SM
  • 测试团队负责人
  • 项目线领导和部门领导

输出问题与AP

个人感悟

  1. 这个一天的工作坊时间非常紧,中午到十二点半,下午到7点半
  2. 即使超时也要认真做完,因为沉默成本很高
  3. 领导一定要全程在场,进行参与、把关、决策,否则过程中很容易大而化之
  4. 前期工作和人员选择要匹配,确保可以拍板的干系人都在场
  5. 问题被抽象化了,所以解决方案没有能够带入进行推演验证
  6. 整个工作坊,是有讨论边界的:确定资源开销额度了即使不合理、需求已经不能减少了、需求优先级已经不能调整了等。这些限制(或者隐形限制,领导的决策)对工作坊输出方案有效性会造成影响?

2022年能力提升策划

目标

对于能力之前的理解都是,是否可以做TDD、需求分析、业务能力、架构设计等等具体的能力项。但是这些能力能够解决问题是零散的,没有聚焦在一个完整的职业需要的技能上。 现在我转换了一下思路: 假设我现在离职了,需要换一家工作,那么我想些什么工作呢? 结合我现在的基础,我想做软件工程后中间一段的事情,包括:需求分析(偏向软件侧)、架构设计、软件设计、这样的事情。具体到实际可能的职位:

  • 开发团队的教练
  • 产品架构师
  • 技术Leader 基于要达到这个目标,我需要具备的能力就可以场景化为:
    一个公司在做一个产品时,遇到各种设计和开发中的问题,需要一位教练来改善软件研发过程。
    今年的目标就是作为教练能够指导一个团队完成产品分析和落地。

虚拟推演

在这部分,假设我做为敏捷技术教练进入一个团队,辅助这个团队完成软件产品的改造和能力提升。按照时间顺序推演整个过程包括如下环节:

  • 组织业务专家和技术专家完成问题复盘,总结出各个环节的问题。后面在不同环节进行分别寻找办法
    • 在这个过程中,需要组织会议进行复盘(如何进行引导,问题又如何确定是真正的问题,如何确定到最本质的问题以及不可变约束)
    • 需要区分哪些软件开发环节,这些环节又是基于什么划分的?
  • 需求分析:描述需求、确定问题域范围、需求实例化、需求分析规范和格式
    • 需求描述,需求实例化,明确解决的问题,以及需要解决的场景和外部系统
    • 输出需求分析的DoD
  • 收集非功能需求:扩展性、性能、可靠性、成本等
    • 这些也要考虑并合并到上面需求实例化中
  • 通过前面问题域内容:进行架构设计、通用域选型(服务框架、中间件、语言、软件框架),规格标准确定
    • 考虑当前确定因素(软、硬)
    • 进行系统架构设计
    • 进行组件软件架构设计
    • 进行外部设施的选型
    • 进行语言的选型
  • 进行敏捷中需求队列,任务排序的实施,迭代的制定
    • 交付管道的敏捷流程管理方式
  • 进行软件架构的搭建(DDD战术设计),并且进行开发指导(TDD)
    • clean architechure
    • tdd + DIP + 端到端
  • DevOps搭建
    • AC + 自动化流水线

以上具体推演总结各个环节的实践经验,并且将每个环节进行详细描述,并通过实践经验进行串接。

过程中任务拆分


结构体的导出

一个关于解决配置项问题的例子

下面这个例子中,要解决的是在执行时,可以灵活设置所有配置项。
而且这个配置项还有可能会持续变化和增长。
例子开发的是一个Go语言包,该包种有一个操作 Foo:

// 通过Option进行所有选项的设置,传入的选项是一个option类型的函数,这个函数可以设置一个指定的选项
// option类型是:type option func (*Foo)
// 代码如下:
func (f *Foo)Option(opts ...option) {
  for _, opt := range opts {
    opt(f) // 遍历执行传入的设置选项函数,这个函数的参数都是Foo对象本身,用于修改Foo对象的选项配置
  }
}

// 下面是一个选项的函数实例,设置:
func Verbosity(v int) option {
  return func(f *Foo){
    f.verbosity = v
  }
}

// 下面是调用实例, 选项设置并不需要修改Foo的代码:
foo.Option(pkg.Verbosity(3))

// ------------------------------------------
// 下面是在上面的基础上,在设置选项参数同时返回设置之前的初值:
type option func(*Foo) interface{}

func Verbosity(v int) option {
  return func(f *Foo) interface{
    prev := f.verbosity
    f.verbosity = v
    return prev
  }
}

func(f *Foo)Option(opts ...option) (prev interface{}){
  for _, opt := range opts {
    prev = opt(f)
  }
  return prev
}
// 调用实例
preVerbosity := foo.Option(pkg.Verbosity(3))
foo.DoSomeThing()
foo.Option(pkg.Verbosity(preVerbosity.(int)))

// -----------------------------------------
// 上面的类型判断何有些笨茁,下面是优化
type option func(*Foo) option

func Verbosity(v int) option {
  return func(f *Foo) option {
    prev := f.verbosity
    f.verbosity = v
    return Verbosity(prev)
  }
}

func(f *Foo)Option(opts ...option) (prev option){
  for _, opt := range opts {
    prev = opt(f)
  }
  return prev
}
// 调用实例
preVerbosity := foo.Option(pkg.Verbosity(3))
foo.DoSomeThing()
foo.Option(preVerbosity)


参考文献

  1. 自引用函数与设计

Beego的端到端测试

Beego的router注册机制

Beego是借助Go语言对于模块的import机制自动完成router(URL和controller的map)注册执行的。
Go语言模块的import机制如下图示例: 是先执行import模块的import,然后执行import模块的const申明,var申明,init()函数。
/* TODO: 补充参考一中的图 */ Begoo框架就是利用这个init自动执行的go语言特性:

  1. 在router模块的init函数中执行router注册函数,建立url和controller的map
  2. main文件中import router的模块,就可以自动完成router的注册。main函数中只需要把框架跑起来就行了(beego.Run())

端到端测试

根据Beego的router注册机制,我们可以发现在单元测试时只要import router模块就可以实现Beego框架中router的注册.

具体实施有两种方法:
第一种,使用httptest库进行测试。httptest有一个NewServer的函数,结合Beego提供的一个http的handle(beego.BeeApp.Handlers),
就可以启动这个fake server,然后使用http.(method)进行请求触发,见参考二。
第二种,直接使用Beego的serverHTTP,beego.BeeApp.Handlers.ServeHTTP(rsp, req)触发router服务。
这里的rep用httptest的NewRecorder()创建,req用httptest的NewRequest()创建。

参考文献

  1. Beego路由设置
  2. A good way to do tests for beego router

—  原创作品许可 — 署名-非商业性使用-禁止演绎 3.0 未本地化版本 — CC BY-NC-ND 3.0   —