我在德国做SAP CRM One Order redesign工作的心得
时间过得很快,今天是我到德国工作的第四周,刚好一个月。Prototype的框架已经搭起来了,现在Order能够在新的框架下正常读写,能跑一些简单的scenario,这些scenario对于end user来说感觉不到任何区别,因为毕竟只是DB layer变了。
从下周起就是第二个月,要解决一些open question,比如STATUS, DOCUMENT FLOW这些后台存在SAP_ABA的表,怎么合到新表里去?这些都是接下来要解决的东西。
what I have done in first month
one order这个workstream只有Carsten, Oliver ( IMS guy, one order expert ) 和我,而Oliver只有50%的resource放这个workstream上。POC 4300行左右代码,平均下来按1周5天算每天也就写200行。 属于我名下的一共有46个bug,不过都已经fix了,平均下来我每写93行就要生产出一个bug, 囧。不过我之前和一些同事提过,框架开发的复杂度比应用程序开发要高。
举个例子: 创建新的service order,维护header的shipping data,此时order和shipping data的mode 都是creation,然后创建line item,添加product,header的shipping data带到line item,然后在line shipping data做修改,item的mode变成了change,此时不存盘,直接删除该item,然后马上另外创建一个item,继续编辑,此时第二个item的mode是creation,前一个item的change mode变为deletion,然后再删除第二次加的line item,不存盘,再创建第三个product,维护一些数据,存盘。此时我代码里的buffer处理会出问题,存到DB确实有一条item数据,但是已经corrupt掉了。 由于我buffer处理logic有bug, 我花了很大功夫最后发现是第二次被删除的那条数据的内容被错误存到了DB里:
我甚至花了大量的时间来找重现这个错误的办法,因为最初我是偶然的机会发现这个错误,但是没留意我的操作,我花了很长时间在屏幕上进行各种操作,最后才找到能稳定复现问题的步骤,赶紧记录下来:
这个buffer处理的bug直接导致了某天有4个新bug开到我头上:
第二阶段 Design improvement - 被Carsten虐
第一阶段,也就是前半个月,我加了很多班让one order能够在新框架下跑起来,然后进入后半个月,也就是第二阶段,对Design的不断改进。
大家都知道老的One order,header和item的administration信息都是存CRMD_ORDERADM_H和CRMD_ORDERADM_I, 然后其他的order节点,每个节点都有1张表,这些表总共有1368张,每次你保存的时候,不同的数据进不同的表。
现在新的design下,所有这1368张表都不要了,所有的数据都往新的Header和item塞。怎么弄?Carsten在我来之前remote和我沟通,说他有一些draft idea,但不sure是否真的能work,需要我把这些idea变成可以运行的代码,run起来之后走一步看一步。Carsten的draft idea很粗,没有实现细节,因此我有充分发挥的空间。
第一阶段我的框架搭起来之后,我自以为实现的很精妙,代码量又不算太多(2000多行),又能够工作,我自我陶醉了。
第二阶段我们每天上午有半个小时的sync meeting,下午有ad hoc的meeting。 上午sync meeting的agenda: 把当前我写的POC代码分成若干块,每天review一块
- review昨天那一块的rework结果
- review今天应该看的那一块
也就是说,这半个小时是我们三个人坐在一起,通过看我的POC代码来改进design。本来是我把代码打到大屏幕上一行行解释这些代码做什么事情,但是实际根本不需要,Carsten看代码速度非常快,反应速度也很快(也可能是我代码可读性实在不错)。我代码质量没任何问题,我自认为算一流,Carsten却每天都能找出需要rework的地方,这些需要rework的都和design相关,比如这件check不应在method A处做而应放到method B处,某逻辑不应放在class A而应放在class B做。所以我第二阶段每天的流程一般都是: 上午review, 下午rework, 改bug. 改bug的时候,我会增加一些代码,这些新增代码又会成为第二天review的input, 周而复始。
我觉得这一个月我收获最多的地方,就是可以和Carsten work on the same topic, learn why he disagrees with my design / code. 因为打比方,如果让Carsten给我做one order的training,我想对我不会有任何帮助。Oliver在我到的第一天问我需不需要他给我讲些one order的session,我说no no no,直接开工吧。我每天和Carsten review他都会找出毛病,而且他挑毛病的尺度和评价标准很值得我学习- 有些毛病他会说,你现在这样做,POC没任何问题,以后productive实现再改。有的毛病他则说,你这样不行,必须改。我事后也会暗自揣摩,他做这些判断的依据。
以前Wuji告诉我,他最开始想学编程,但是没任何基础,不知道怎么入门,所以花1400/月找了一位川大计算机老师,每周三天去这位老师家让他给Wuji讲些计算机基础。所以我现在把自己每天做的事情当成一个类似北大青鸟的培训,这个培训每天有T5的Chief Architecture作为我的老师, 能够和我坐在一起,就一个具体的项目一起动手做,既有纸上的项目设计,又有上机作业,而且这个老师还会认真批改我的作业,这种机会太难得了。我做的越多,就会有越多的机会让老师帮我批改,我就能学的更多。正因为这样想,我每个周末哪也不去。
第一副图是我改了无数版的Order save的实现,我觉得已经相当不错了,但是今天Carsten review的时候,还是给出了修改意见,reason就是看起来很简单的single responsibility. 这个原则说起来容易实现做起来难。
两幅图比较起来,看起来我的design代码量更少,更简单。Carsten的更复杂。但这只是表象,实际上我的视线把buffer merge这个框架需要做的事情注入到了One order 模型每个节点的convert class里去了,就是那个叫convert_1o_to_s4的方法。而One order 模型比方说有200个节点,这些merge的事情就要重复做200次。而Carsten的理由很简单,就是single responsibility,convert class不应该做的事情,不应该感知到的东西,坚决不去碰。 今天我刚才按照Carsten的proposal把整个framework做了refact,结果确实是,改进后的framework代码量更少,因为所有convert class里duplicate的 buffer merge动作都提取到class外面来了,也就是第二章图里那个棕色的method。
Carsten的这个proposal我最初脑子里也曾想过,但我觉得如果放到外面,这个method要能handle任意格式的Order node数据,而且需要能检测出Creation, Deletion和Update的任意一种模式,我觉得编程复杂度过高,没法给出effort estimation。如果放到convert class内部,那么内部convert class知道自己具体是什么structure,所以structure在convert里能够写死,这样做buffer merge简单得多。因此我做POC就按照简单的实现来做,没想到最后还是被Carsten callenge了。这个refact让我总结出一条结论,如果是做框架开发,具体实现复杂度不能成为影响design的决定性因素(作为参考可以).
要获取更多Jerry的原创文章,请关注公众号"汪子熙":
我在德国做SAP CRM One Order redesign工作的心得的更多相关文章
- 我做SAP CRM One Order redesign的一些心得体会
框架开发和应用程序的开发完全不一样. 举个具体的最近折腾我的例子: 创建新的service order,维护header的shipping data,此时order和shipping data的mod ...
- SAP CRM One Order跟踪和日志工具CRMD_TRACE_SET
事务码CRMD_TRACE_SET激活跟踪模式: 在跟踪模式下运行One Order场景.运行完毕后,使用事务码CRMD_TRACE_EVAL: 双击参数,就能看到参数明细: 点Callstack也能 ...
- SAP CRM One order里user status和system status的mapping逻辑
Below example show: How the mapping relationship between User status and System status maintained in ...
- SAP CRM系统订单模型的设计与实现
SAP成都研究院的一个部门领导让我给他的团队做一个SAP CRM One Order框架的培训,这是我准备的培训内容. 在Jerry之前的文章 基于SAP Kyma的订单编排增强介绍,我表达了自己对S ...
- 给用过SAP CRM中间件的老哥老姐们讲讲SAP CPI
最近Jerry由于项目需要,又得学习一个新工具:SAP Cloud Platform Integration,简称CPI,以前又叫做HCI - HANA Cloud Platform Integrat ...
- 浅谈SAP CRM和Hybris Commerce里的价格架构折扣
最近Jerry做了一个和价格折扣相关的原型项目,把学到的知识记录下来,以备将来查阅. 在这个原型项目里,我们用React-Native开发了一个移动应用,用户可以在手机上浏览SAP Hybris Co ...
- SAP CRM 树视图(TREE VIEW)
树视图可以用于表示数据的层次. 例如:SAP CRM中的组织结构数据可以表示为树视图. 在SAP CRM Web UI的术语当中,没有像表视图(table view)或者表单视图(form view) ...
- SAP CRM 项目笔记(一) SOW(工作说明书)讨论
前记 前两天在搜索资料时,看到一个网友在博客里面记录下了自己参于项目中的所有笔记.我觉得这个想法很不错,所以决定开笔记录下SAP CRM整个项目的实施和开发过程. 之前参加集团的SAP ERP(FI/ ...
- SAP CRM 最新简介文字(2007年、中英文)
以下内容是SAP CRM功能的精简描述,摘自SAP官方文档,附上中英文版本,可以对SAP CRM的主要功能有大致了解. 营销 - 使用营销资源管理.客户细分及列表管理.营销活动管理.线索管理.贸易促销 ...
随机推荐
- javascript实例——文本特效篇(包含3个小例子)
1.标题跑马灯 常常能够在一些新闻网站,或者其他地方,看到文字在一个特定的区域内,来回滚动.一旦超出边界就消失了,那么这些效果是如何做到的呢,今天我们就来讲讲. 图示效果: 源代码: <!doc ...
- ABP学习入门系列(三) (领域层中的仓储Repository)
一,仓储定义:“在领域层和数据映射层的中介,使用类似集合的接口来存取领域对象”(Martin Fowler) . 仓储用来操作数据库进行数据存取.仓储接口在领域层定义,而仓储的实现类应该写在基础设施层 ...
- mybatis在oracle中的分页扩展
applicationContext.xml <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlS ...
- 撩课-Web大前端每天5道面试题-Day17
1.apply, call和bind有什么区别? 三者都可以把一个函数应用到其他对象上,注意不是自身对象. apply,call是直接执行函数调用,bind是绑定,执行需要再次调用. apply和ca ...
- dubbo的重试机制
对dubbo熟悉的人对下面的配置一定不会陌生: <dubbo:reference id="xxxx" interface="xx" check=" ...
- golang chan 发送接收测试数据
测试代码: package main import ( "fmt" "time" ) const ( num = 10000000 / ...
- Vue 中的 v-cloak 解读
v-cloak 的作用和用法 用法: 这个指令保持在元素上直到关联实例结束编译.和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Must ...
- 小程序:获取input输入的值
wxml <input placeholder='输入你的姓名' value='{{name}}' bindblur='nameblur'></input> js data ...
- 从项目中学习HTML+CSS
最近由于工作原因以及自己的懈怠,已经很久都没有更新过博客了.通过这段时间,我发现坚持一件事情是真的很难,都说万事开头难,但是在放弃这件事上好像开头了后面就顺理成章的继续下去了.中间即使不怎么情愿也在努 ...
- python中垃圾回收机制
Python垃圾回收机制详解 一.垃圾回收机制 Python中的垃圾回收是以引用计数为主,分代收集为辅.引用计数的缺陷是循环引用的问题.在Python中,如果一个对象的引用数为0,Python虚拟 ...