您的位置:首页 > 运维架构 > 网站架构

编程设计-如何写可维护的程序. 通往架构思维之路

2015-11-13 14:29 441 查看
初级码农写代码(码代码)经常会遇到代码复用,重构,方法生成,方法命名的问题.

有本专门重构的书, 看了也忘记了.过几天重温下. 先写自己的思路.

通过别人专业的书来让自己在非专业领域里突显深度, 突显思考的维度.  靠自己想, 思考维度永远是比较弱.

模块设计:

               三个阶段: 1.垂直拆分,水平拆分, 垂直+水平拆分.

设计:

          1. 依据垂直水平拆分的原理:

                   一张表承上启下, 有一个字段是自己本身这层业务的(主分类). 有一个字段是外部(存储用,子分类).

                   这个有点类似一个基础服务对外暴露功能.

                    trade cashier层最大的问题是 type 没有大分类. 用处是 1.自下而上匹配上游业务  2.unique 检测 .

                重构: 增加 mainType 的同时. 不能删除原来的 type. 但是 unique 健可以增加 mainType, 这样代码上 bizType 就不需要用同一个枚举类.

                 将一个100个 type 值的枚举,拆分为5个枚举类. 不用担心值相同冲突.               

                 带引擎层的拆分. 上层业务层也包含了所有流程. 基础服务层也包含了所有流程.
这样拆分采用意义.

                 另外: 下层的引擎层,每一流程都是一个模块.
但是上游业务可以放置在一个模块里.

   
           2. 异常逻辑考虑.

                  返回错误码.

          3. 模块重构将一个模块,拆出. 原则是:拆出的部分一定要稳定. 可以当存储,但是不要杂糅业务含义. 不然会很奔溃.

                  例如帐户模块: 可以把 uid 包进来, 但是不能把 担保金帐户什么的概念包进来.
只是 type的概念,不会进行校验什么的.

                 这点估计一般人比较难想到,能想到拆出来,但是不知道怎么拆.

           4. 一个类型独立成一个模块. 这个模块需要统一的 remote 层. 然后内部有 bizServic, service dao 层.

                  这个往大了说, 其实就是模块拆分了.

                 先分渠道,每个渠道又是 拉新,留存.

1. 犹记当年广告系统复杂,N种广告揉在一个系统,表面上表结构都一致,但又有区别且流程不同。

2. 按垂直领域切割后,依然存在问题。一个流程中分为下单,抢单,投放,结算逻辑。可以独立模块。

3. 按流程切割后,又遇到本身表的基本操作和复杂操作问题。多表操作问题。?

第三步才是初级码农遇到的困扰: 解决方案是,借鉴大模块切割理念,将不同的表认为不同的流程,以不互相依赖为原则切割的话,可以把哪些逻辑下沉到属于上游表的service中。

并且另外一张表的service可以调用上游表的service,但不能互用。

4. 面向接口编程:   1.归集方法(去除type判断,策略)  2. 反向依赖,抽取引擎模块. 作为底层. 3. builder等模式提高代码可读性.

5. 面向性能编程. :  1.表设计 切割 2.锁力度 3.mq消息接受 3. 索引命中 order by id ,无id值.

6. 面向兼容性编程. 1.老数据影响?  2.过渡期,双写,数据转换.

第三步中,可能可以分成多个层级的维度. 如何选主维度.每个二级维度是否需要继续继承实体. 继承爆炸?

   例子: 代保养,普通代驾的支付业务怎么拆分. 既有业务,又有渠道的维度. 代保养微信支付,普通代驾支付宝支付. 主渠道怎么选?

   如果一上来就想着先分代保养,还是先分支付宝就有问题了.

   先看看支付流程有哪些逻辑:

      1. 获取支付费用

      2.渠道支付两部分.

   显然第一个流程. 代保养和普通代驾对业务的影响更大. 此为主业务. 对于第二个流程, 代保养和普通代驾对业务影响不大. 不需要专门继承,只需要简单的一个字段即可.

   很完美的解决.

这样就不会出现组合爆炸,A和B要组合,B和C要组合,A和C要组合。

而是变成了。 A是上游,B调用A,C是调用B和A。

其他通过反向通知的机制通知即MQ或者返回值。 

总结:模块内部的层次应该是N层的。首先是上游模块的(Cdao Cservice,BService,AService),(Bdao,BService,ASerivce),(AService,ADao)然后一层层往上垒,利用友元限定。可能在不分工程的代码内会越来越混乱。1.首先没有技术壁垒限制 完全依赖规范 2. 规范很难执行 3.本身开发者对各友元依赖关系不明了。导致层次混乱。

取名 kuaipayService 还是 取名 transferService。

transferService必须放到kuaipay包下面,表示这是kuaipay领域的,特别是针对需要Write-ahead-log。用于对账的。

打车系统中也是。快的,出租车,专车。 垂直领域最好重新开发,分开。如果真的非常耦合,可以下沉为一个共同系统。the one。只是简单的存储作用。

三层切割: 垂直领域切割,大模块切割,上下游再切割。

故: 接手系统首先不是入口业务分析,而是分析表的生成顺序(上下游顺序),和同一张表能否切割具象为N张表。

  分责任:1. 按表分,另外按流程切割,2. service 也按上下游模块隔离开。

无法技术隔离,那么就利用友元隔离。

一个方法被调用多了,就需要封装了。自动统计,重构点。好维护点,将参数减少法。下层法。模块隔离法。

拿到一个需求,如何写出代码.

第一步, 了解流程.

第二步, 切割流程 (以那个为主体切. 流程维度.业务维度,支付渠道维度. 三个维度. 主维度确定后,不要继续继承了,通过组合,含业务字段,渠道字段.然后分拆. 继承继承的是属性.)

     如何切割,
垂直切割,水平切割的总体思想. 先想好框架,领域实体也可以按这个思路去设计.本来是平行的模块.垂直切割开.垂直领域.

             1. 调用分为那几步.,每一步都可以变成一个类(类比方法的好处是独立文件,更直观, 更容易搜索和记忆,便于以后维护)

             2. 每个调用和调用后的处理都可以分为两个类. 每个分支一个类. 复杂逻辑易于后期维护和扩展.

     比如支付里的. 支付和支付回调. 支付和支付成功入账处理

第三步,每个流程整理领域对象.

举例: O2O项目,有接单,抢单,结束服务,支付,分润,入账,.

细节:

1. 有些业务必须原子操作,采用事物.或者采用幂等重试的思路. 幂等两种, 幂等插入法, 幂等状态检查法. 都需要事务封装. 

幂等分流.

        2. 锁和并发. 

        3. mysql limit

        4. 分布式锁的finally unlock的 是否本线程加锁的判断.

        5. join 框架的实现. 这个没有去思考执行过程,只有输入输出,没有过程,过程是要自己想的,这个比较难.输入是图,输出是数据. 实体是混沌中整理出来的.按此思路重新梳理一遍.

        6. 数据结构,考虑性能,读写,随机读, 写多读少等等情况下的数据结构选择. 这个是技术专家方便. 行储存和列存储的选择. 分词, 时时索引的方案选择. 这个是技术方案.

        7. tcp nio 网络层面的考量.交互
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: