极盗者
这是我自己公众号的文章。 其理由是,公众号的很多文章都是大数据、高并发性等文章,很少有编程思维等文章。 这总结了自己工作中的编程思维,因为它抛砖引玉。
内容
OOAOODOOP人OOA/D/P是解决问题的过程,OO是对象,首要对象是人数的x问题,任何问题都来自人,我认为所有有效的问题解决都是基于团队良好的沟通。
OOA-Object-Oriented Analysis
OOA是指明确所面临的谁的什么问题,如何解决问题的分析过程。 无论是软件开发还是实际生活中出现问题的第一步是分析如何解决问题,军团的战斗只是生活中的琐事
首先是在团队中确立统一的领域的知识。 通俗地说,是共同的话题。 在你的开发项目中或团队交流中有“一个频道上没有”的吐槽吗? 这是共同话题的反面。 在我的项目中,将购买者定义为user、buyer、member、consumer,另外物流解决方案与物流渠道的关系等统一领域的话题是项目成功实施的关键
明确问题的界限,只有在有界语境下分析问题才是正确的。 否则,将一发不可收拾,重点解决主要问题。 例如,由于我公司的业务没有处理商品的质检入库冥等,导致后续后台操作异常,只要解决了质检入库接口冥等,后续的问题自然就会得到解决
明确领域,系统由多个对象及其行动组成,核心领域应尽可能“小而美”。 虽然像人行动一样复杂,但被大脑控制着。 业务)例如,订单的返还核心是第一次的返还额、新人的订单的返还额、有效期内的返还额、有效单位量内的返还额、有效单位量的返还额等返还算法
对象的提取和行为定义可以在面对PRD文档时基于“场景”分割PRD。 例如,根据登录、订单、付款等提取实体并定义其行为方法)
整理对象的依赖关系,了解软件的要素与现实有多么相似,例如对象的生命周期、行为的协作、
托管依赖、对象依赖可以分为同领域内,跨领域,如订单风力发电系统、同领域内的执行器依赖风力发电规则,跨领域依赖订单域的订单数据
定义域联合数据的完整性。 现在,微服务广泛普及,在服务之间,rest风格的API通信是优先的。 随之而来的是数据完整性的问题。 这个问题首先考虑强一致性还是弱一致性? 然后考虑服务分割是否合理。 弱一致性需要补偿。 在实际运用中,由于可以以更低的成本实现,所以倾向于用“补偿式”来解决。 不得已不引入TCC、Seata框架。 给项目带来复杂性。 下述列表和库存的场景在taobao、京东也有超卖品。 我们不仅要尽量避免技术,还必须从业务上解决售后服务的问题
总结商业消息,消息是解除服务结合的利器,无论是同领域内的消息,还是跨领域的消息,如果正确使用消息机制,维护成本往往会降低
同步、异步和同步必须等待执行结果。 例如,创建订单、接收红包等需要同步,但异步细分异步等待、异步通知、异步等待同时执行当前业务以外的操作。 方法返回之前执行await,如果操作完成,则不阻止当前线程,反之亦然。 异步通知完全不会阻止当前线程。 例如,支付经常有第三方渠道的召回操作
识别合并场景,在现实生活中例如进入地铁站,轧机会限制同一时间进站的人数,另外到医院挂号会有窗口。 如果没有这些限制的话会混乱。 业务大多同时写一个数据,但实际上是多个数据、超卖、多按钮等。 辨别同时阅读,同时写作。 尽量不使用通用的全局变量进行写入。 全局读取变量必须事先初始化,解决并发问题最终分类为乐观锁定、悲观锁定-本地/方差
最后,根据结果使用多线程测试业务,如果数据符合期望,则同时安全,否则需要分析其原因
尽早确定风险、项目开发的进度风险、项目发布后的风险、进度风险即影响项目进度乃至失败的因素。 发布后的风险,即上线后影响用户的,是所有使用系统的人。 例如,支付失败会影响用户,风控规则的启动会影响用户的购买过程
如果适当考虑非功能因素,业务出现在PRD上时,主要是业务功能,非功能因素如系统稳定性、QPS承载力、攻防力、容器配额等是系统不稳定之一,需要适当考虑发生问题时应该如何应对、例如熔断电流限制、功能下降、扩展等
适可而止,整个分析什么时候结束? 问问自己,伙伴还有问题吗? 如果有,继续分析,否则进行下一个OOD设计
小结
统一领域知识明确问题边界定义依赖于核心领域提取对象定义行为定义数据的一致性来整理消息识别的同步,确定异步同步识别失败的风险点,提出解决方案并适当考虑非功能因素,将其纳入合适的范围内。 需要无限分析
OOD-Object-oriented Design
OOD即不进行对象设计,分析问题后,设计明确的解决方案。 OOA是构想的归纳,OOD是更具体的技术文件)的生产
p>
梳理接口与OOA业务纵向拆分对应,接口可分为本地interface及面向服务service api,通常分业务聚合api ,业务原子操作service;好处是业务聚合api专注业务实现,聚合各service输入输出,service下沉以稳定为目标。
业务实体类及行为,清晰表达业务意图,如:OrderEntity,UserEntity,AccountEntity,定义其核心行为,如OrderEntity之创建、取消;UserEntity之注销,AccountEntity之冻结,实体可以配合抽象类或者接口实现一系列复杂的行为
单一的业务实体往往是“根”对象,譬如:订单创建,需要商品,用户,账户对象参与,而实际情况往往有不同的营销价格策略影响订单创建,如何完成大对象?,首选“组合+抽象类或者接口”组合方式,抛弃继承是因为继承无法控制深度,组合更直观。抽象类,接口如何选择?抽象类可以做些通用功能,具体变化由子类完成,比如:订单基础价格是不变的而营销价格是变化的,那么抽象就很适合,接口在于定义一系列声明,本身不实现(Java 7增加default关键字,可以默认实现接口,但其jdk目的是接口向下兼容)
分离出领域事件,其目的在于解耦,异步化。譬如,新用户注册成功RegisterSuccessEvent保证注册主体流程后通过MemeryBus发出事件,事件消费者既可以是同JVM进程内消费,也可跨进程消费。再如,订单创建成功OrderCreatedEvent事件,消费者根据事件可发出优惠券或者风控系统消费根据订单事件分析潜在的风险
模板,责任链,桥接模式,这三个模式是我项目中用对最多的模式,模板模式用于定义业务规范,把变化留给子类实现,父类负责组合;责任链模式即明确执行者“责任”,非自己的“责任”往下推;而桥接模式解耦实现与定义从而保证业务结构的稳定性
UML类图,序列图是我常使用对部件,类图把复杂对领域关系图形化,序列图把数据流转按顺序(至上而下)表达出便于团队交流,复杂对序列图按场景分解多个而不是一张大而全的序列图,序列图不足的地方是无法表达复杂的分支判断
小结
接口业务实体根对象领域事件重用设计模式类图,时序图
OOP-Object Oriented Programming
OOP依赖OOA、OOD的成果,实现OOP首先需要两套框架,其一做业务实现首选spring boot),其二一套分层良好的脚手架,我工作中业务module:
x-api:restfull接口入库模块x-domain:业务实现模块,业界也有叫做service,个人认为领域更贴切x-facade:外观模块,聚合领域多个实现组合业务功能x-suport:支撑模块,提供项目依赖工具x-integrate:集成模块,业务防腐层实现所有依赖service api调用x-dao:数据访问模块,也有叫做仓储x-test:业务测试模块,所有功能单元测试聚集之地
x是项目名称,我在项目中对第三方框架做胶水代码整合,使之更加适合业务开发,而非直接套用第三方框架
OOP原则开放封闭,单一职责,多情的乌冬面替换,依赖倒置,迪米特法则,合成复用我认为做好开放封闭、单一职责即可,但这是很难的,难处在于软件设计开发中很难界定对与错,业务如何变化不可预见,代码好也罢烂也罢机器都认识,这些原则都是团队间的交流基础,维护成本,交流顺畅则解决问题高效反之低效,如何达成OOP原则?,其一设计模式,其二重构,二者是解决系统重构是解决系统疑难杂症的良方,不可不读
AOP是业务增强功能利器,譬如:监控接口成功率,耗时时长,过滤等
汲取业界通用编码规则是个很好的参照,保持跟同行编码水准,避免常识性犯错
小结
框架多模块OOP通用法则业界编码规则
人
传统的OOA,OOD,OOP并没有对人但思考,但物以类聚人以群分,个体的人组成的团体,团队角色不同其视点视角不同,每个人对事物理解不一样这都影响项目成败都因素,达成一致即为OOA、OOD、OOP最终产出形态
团队中成员技能水平,知识视野都存在差异,那么需要做到人尽其才,譬如:精通业务者使其开发业务核心代码,精通框架者使其开发框架为项目保驾护航,而那些刚入行经验甚少者使其执行具体任务(做什么)即可
补充
行内一直有DDD领域驱动跟传统OO领域驱动,DDD更丰富知识体系更复杂适,如:战略设计,实体,值对象,领域服务等,其实这两种方法论也是有交集的,如:边界,核心域。二者都是建立在团队基础之上,到底使用那种方法论,看团队成员的认知,勿强推DDD。更多的是从解决问题实际出发,所谓黑猫白猫抓到老鼠就是好猫
小结
关注团队成员视点视角团队达成最终一致团队成员各施所长
相关资源推荐
软件架构设计模式精解重构重构与模式UML与模式软件架构视点视角及利益相关者恰如其分对软件架构