最近在做一些业务拆分的工作,需要把所有耦合的地方一个一个进行拆分,并测试功能可用性。
任何事情都不是白做的,业务需要拆分也说明当前架构不是很合理。为何当初业务要合并在一起,导致现在要花大时间拆分,说来有趣,当初的合并也是我主导做的。我会讲述这个过程,为了避免项目信息外传,这里我就用字母代替项目的真实的项目名字。
最初,项目刚成立时,由于业务的不确定性、用户体验的尝试、功能的单一化、数据量并发量不高、开发资源少,等等诸多因素,项目开发的特点是:
无架构 —— 项目前期灵活多变,有些功能为试探性,可随时砍掉,过于关注架构会导致开发缓慢,且功能增删频繁会导致架构不稳定、甚至最初的架构变得不合理,最终陷入架构困扰开发。
低耦合 —— 不同功能往往都是独立的,互相无牵扯的,所以功能开发耦合低,甚至一个功能就是一个代码文件,不同文件组成了不同功能。好处是,开发人员工作高效,提交代码互不影响,A同事负责1/2/3功能,B同事负责4/5/6功能。
混逻辑 —— 正如上面提到了灵活多变,因为业务代码可能被频繁改动,往往设计了一个方法,传四个参数返回一个布尔值,可能到项目上线时,这个方法已经变成了传6个参数返回一个数组。可想而知,这个过程中会将函数的实现逻辑改来改去,业务逻辑随之变得复杂甚至混乱。
少注释 —— 最初项目开发,一位追求精细的注释会很被动,说不定今天加的注释,明天代码就变了。而且开发人员往往认为,现在就这么几个功能,而且又这么简单,没必要加注释。
快迭代 —— 这个算是个总结,程序的分散、独立,编码的高效,业务的快速更新、新增和删除。
如图所示,不同的人开发维护不同的业务逻辑,几乎没有交集,工作互不打扰。
然后,随着功能的复杂,已经不能由单个人员维护了,而且功能之间也存在互相调用了,现有的这套逻辑已经无法满足业务场景了,经常会出现各种问题,包括不限于:
1. A功能需要给B功能提供接口,导致A功能函数复杂。
2. 一个需求往往需求由A、B、C多个功能共同完成,需求难开发,需要调用多个请求才能实现,非常低效,甚至程序执行时间变慢。
3. D功能由一个人维护变成多个人维护,由于D还需要给C功能调用,负责C的开发人员偶尔还会去改D功能,结果D被很多人不停地修改蹂躏,最终难以维护。
4. 等等。。。
这个时候,大家会吐槽代码不好维护,职责不清晰——往往我们听到这样的声音,很有可能就是遇到上面这类问题了。这时我们需要考虑架构了,其实也不复杂,我们的核心问题是解决功能高耦合。如何解决呢,就是站在更高的角度看待当前所有需求,不要再将需求按照功能拆分,而是将需求按照模块进行分析,拆分出很多个绝对独立的模块。
面对这些模块思考:
我们有多少独立的模块?
这些模块能否满足所有功能?
有哪些模块太零散或者不适合当做模块?
零散的模块是否可以和其它模块整合?
梳理完,我们得到合理的、可封装的一系列模块。举个例子,比如登陆注册功能,我们可以拆成用户的数据库操作模块、密码管理模块、用户管理模块、权限验证模块,这些模块不仅给登陆注册用,还可以给其它功能用,比如有个活动功能需要展示用户数据,可以直接调用用户管理模块。模块的设计有一定挑战性,需要考虑是否合理、是否通用,好的模块不会因为功能的修改而修改。那么,当前的架构可能会如图所示。
这时,核心的代码都被封装到模块中,有对应的人去负责维护。而功能层面,多个人同时开发也没有问题,因为模块不会受到影响。此时项目的稳定性、灵活性,都是围绕模块为核心,在模块之上,产品功能可以进行各种快速的迭代开发。
后来,公司越来越大,产品线越来越丰富,产品经理也越来越多,开发资源却会觉得越来越稀缺。每天产品和程序员都会进行一轮又一轮的较量,如果程序员赢了,那么功能就会被砍掉很多,或者时间排期安排的更充裕以便做质量好的项目,总之程序员胜利的那个时刻会是非常幸福的。现实对于程序员来说,却是灰色、阴暗、悲惨与恐惧的,因为大部分时候都是产品经理们完胜。。。
这个阶段,对于程序员存在一个铁律,那就是:
1. 产品需求做不完的做,做得越多觉得积压的需求越多
2. 开发资源总是不够
对于第一条,其实很好理解,当你或者你们部门每天工作完成的任务量越多,产品会觉得,我勒个去,这帮程序员做的怎么这么快,是不是我们给程序员的工作量太少了,呵呵,你懂得,加量呗。这种公司,是可悲的,能力允许,不建议一直待在这样的公司中:
因为你的工作高效而不加班,往往leader或者产品会认为你的工作不饱满。
产品经理也知道开发资源稀缺,他们会帮程序员想办法节省工作量。节省的办法很巧妙,就是利用现有的已实现的功能模块进行改造、拼合并包装,往往需求讨论会上你会听到产品这样说:
1. 这个功能我们以前做过,直接拿来用,改几个字符串就行,很快的
2. 这个需求最复杂的是巴拉巴拉逻辑,而巴拉巴拉逻辑那谁谁实现过,你们看看那块逻辑代码能不能直接用,应该很快的
3. 市场要做个活动,很简单,我们只需要做个活动页面就行,然后用现有的登陆注册等流程就行,很快的
4. 等等诸如此类的话
没有经验的程序员往往会很高兴,哇塞,工作量不多哎!我以过来人的身份告诉你,不要被坑了!
1. 新需求往往有一些改动,而这些改动导致以前的功能代码必须要大改才能用,坑
2. 你找到巴拉巴拉负责人,要他的代码支持产品需求,那个负责人一般会告诉,巴拉巴拉逻辑代码根本不是干这个的,产品啥也不懂,坑
3. 市场做活动,我需要登陆注册后引导用户进入指定流程,我需要转换率的统计,我需要给参加活动的注册用户一些诸如代金券的奖励,妈蛋的,感觉现有的登陆注册功能好单薄啊,坑
4. 坑坑坑。。。
如图所示,越来越多相类似的功能,不同产品的代码复用,给不同业务提供强大的可扩展性。模块的设计,也由最初的简单变得复杂、臃肿、难以维护,这个时候往往一个模块会给多个功能使用,甚至多个不同项目使用。此时的架构,程序员维护模块的成本越来越大,模块的方法、参数也变得复杂和难以理解。
终于有一天,大家都觉得当前产品开发效率变低了,程序员疲于维护项目,决定对当前项目架构进行改进。
需要解决的核心问题是去依赖化,让底层的逻辑清晰,项目之间减少依赖,独立成体系。避免像上面架构那样,一个程序员维护一个模块时,需要关心n多个需求和兼容,而应该是不同项目由不同开发人员维护。只有这样,才能保证项目的健壮性。
现在各个项目的开发运转的都很顺畅,那么,当前的项目结构就没有问题了么?其实也不是,公司会继续发展,项目也会继续发展,达到一定程度,就会发现,这些项目中还是存在很多交集的。比如日志系统、监控、数据库的封装等等,而如果每个项目都完全独立开来,会导致每个项目都要有专人去做这些事情,开发资源存在重复工作。因此,随着壮大,又会专门抽出一拨人做更底层的代码封装和维护,才能保证开发资源的合理利用。
正所谓“今天下三分,分久必合,合久必分”,项目、人员、代码拆了又合,合了又拆,这个过程中我也思考了很多。
站在发展的眼光看待,当前的一切都是不合理的。
工作如此,生活亦如此。不要纠结绝对的对与错,找到当下生活的平衡点才是最重要的,很有可能现在的你觉得对的事情会被未来的你所摒弃。成长是一个过程,这个过程会不断地打破平衡然后再次寻找一个新的平衡。
Leave a Reply