写点什么

阿里 P8 级大神经验分享,怎样成为一个优秀的架构师?(1)

作者:Java高工P7
  • 2021 年 11 月 12 日
  • 本文字数:3642 字

    阅读完需:约 12 分钟



1、OCP(开闭原则):设计良好的软件应该易于扩展,同时抗拒修改。这是我们进行架构设计的主导原则,其他的原则都为这条原则服务。


2、SRP(单一职责原则):任何一个软件模块,都应该有且只有一个被修改的原因,“被修改的原因“指系统的用户或所有者,翻译一下就是,任何模块只对一个用户的价值负责,该原则指导我们如何拆分组件。


举个例子,CTO 和 COO 都要统计员工的工时,当前他们要求的统计方式可能是相同的,我们复用一套代码,这时 COO 说周末的工时统计要乘以二,按照这个需求修改完代码,CTO 可能就要过来骂街了。当然这是个非常浅显的例子,实际项目中也有很多代码服务于多个价值主体,这带来很大的探秘成本和修改风险,另外,当一份代码有多个所有者时,就会产生代码合并冲突的问题。


3、LSP(里氏替换原则):当用同一接口的不同实现互相替换时,系统的行为应该保持不变。该原则指导的是接口与其实现方式。


你一定很疑惑,实现了同一个接口,他们的行为也肯定是一致的呀,还真不一定。假设认为矩形的系统行为是:面积=宽*高,让正方形实现矩形的接口,在调用 setW 和 setH 时,正方形做的其实是同一个事情,设置它的边长。这时下边的单元测试用矩形能通过,用正方形就不行,实现同样的接口,但是系统行为变了,这是违反 LSP 的经典案例。


Rectangle r = ...


r.setW(5);


r.setH(2);


assert(r.area() == 10);


4、ISP(接口隔离原则):不依赖任何不需要的方法、类或组件。该原则指导我们的接口设计。当我们依赖一个接口但只用到了其中的部分方法时,其实我们已经依赖了不需要的方法或类,当这些方法或类有变更时,会引起我们类的重新编译,或者引起我们组件的重新部署,这些都是不必要的。所以我们最好定义个小接口,把用到的方法拆出来。


5、DIP(依赖反转原则):指一种特定的解耦(传统的依赖关系创建在高层次上,而具体的策略设置则应用在低层次的模块上)形式,使得高层次的模块不依赖于低层次的模块的实现细节,依赖关系被颠倒(反转),从而使得低层次模块依赖于高层次模块的需求抽象。


跨越组建边界的依赖方向永远与控制流的方向相反。该原则指导我们设计组件间依赖的方向。


依赖反转原则是个可操作性非常强的原则,当你要修改组件间的依赖方向时,将需要进行组件间通信的类抽象为接口,接口放在边界的哪边,依赖就指向哪边。


6、REP(复用、发布等同原则):软件复用的最小粒度应等同于其发布的最小粒度。直白地说,就是要复用一段代码就把它抽成组件,该原则指导我们组件拆分的粒度。


7、CCP(共同闭包原则):为了相同目的而同时修改的类,应该放在同一个


【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


组件中。CCP 原则是 SRP 原则在组件层面的描述。该原则指导我们组件拆分的粒度。


对大部分应用程序而言,可维护性的重要性远远大于可复用性,由同一个原因引起的代码修改,最好在同一个组件中,如果分散在多个组件中,那么开发、提交、部署的成本都会上升。


8、CRP(共同复用原则):不要强迫一个组件依赖它不需要的东西。CRP 原则是 ISP 原则在组件层面的描述。该原则指导我们组件拆分的粒度。


相信你一定有这种经历,集成了组件 A,但组件 A 依赖了组件 B、C。即使组件 B、C 你完全用不到,也不得不集成进来。这是因为你只用到了组件 A 的部分能力,组件 A 中额外的能力带来了额外的依赖。如果遵循共同复用原则,你需要把 A 拆分,只保留你要用的部分。


REP、CCP、CRP 三个原则之间存在彼此竞争的关系,REP 和 CCP 是黏合性原则,它们会让组件变得更大,而 CRP 原则是排除性原则,它会让组件变小。遵守 REP、CCP 而忽略 CRP,就会依赖了太多没有用到的组件和类,而这些组件或类的变动会导致你自己的组件进行太多不必要的发布;遵守 REP、CRP 而忽略 CCP,因为组件拆分的太细了,一个需求变更可能要改 n 个组件,带来的成本也是巨大的。


指导原则


除了上述设计原则,还有一些重要的指导原则如下:



1、N+1 设计:系统中的每个组件都应做到没有单点故障;


2、回滚设计:确保系统可以向前兼容,在系统升级时应能有办法回滚版本;


3、禁用设计:应该提供控制具体功能是否可用的配置,在系统出现故障时能够快速下线功能;


4、监控设计:在设计阶段就要考虑监控的手段,便于有效的排查问题,比如引入 traceId、业务身份 Id 便于排查监控问题;


5、多活数据中心设计:若系统需要极高的高可用,应考虑在多地实施数据中心进行多活,至少在一个机房断电的情况下系统依然可用;


6、采用成熟的技术:刚开发的或开源的技术往往存在很多隐藏的 bug,出了问题没有很好的商业支持可能会是一个灾难;


7、资源隔离设计:应避免单一业务占用全部资源;


8、架构水平扩展设计:系统只有做到能水平扩展,才能有效避免瓶颈问题;


9、非核心则购买的原则:非核心功能若需要占用大量的研发资源才能解决,则考虑购买成熟的产品;


10、使用商用硬件:商用硬件能有效降低硬件故障的机率;


11、快速迭代:系统应该快速开发小功能模块,尽快上线进行验证,早日发现问题大大降低系统交付的风险;


12、无状态设计:服务接口应该做成无状态的,当前接口的访问不依赖于接口上次访问的状态。


架构师知道了职责,具备很好的架构思维,掌握了通用的架构框架和方法论,使用架构原则进行架构设计,不同的业务和系统要求不一样,那么有没有针对不同场景的系统架构设计?下文就针对分布式架构演进、单元化架构、面向服务 SOA 架构、微服务架构、Serverless 架构进行介绍,以便于我们在实际运用中进行参考使用。


具备架构师的思维




架构师职责明确了,那么有什么架构思维可以指导架构设计呢?请看下述的架构思维。


1、自顶向下构建架构



要点主要如下:


1)首先定义问题,而定义问题中最重要的是定义客户的问题。定义问题,特别是识别出关键问题,关键问题是对客户有体感,能够解决客户痛点,通过一定的数据化来衡量识别出来,关键问题要优先给出解决方案。


2)问题定义务必加入时间维度,把手段/方案和问题定义区分开来。


3)问题定义中,需要对问题进行升层思考后再进行升维思考,从而真正抓到问题的本质,理清和挖掘清楚需求;要善用第一性原理思维进行分析思考问题。


4)问题解决原则:先解决客户的问题(使命),然后才能解决自己的问题(愿景);务必记住不是强调我们怎么样,而是我们能为客户具体解决什么问题,然后才是我们变成什么,从而怎么样去更好得服务客户。


5)善用多种方法对客户问题进行分析,转换成我们产品或者平台需要提供的能力,比如仓储系统 WMS 可以提供哪些商业能力。


6)对我们的现有的流程和能力模型进行梳理,找到需要提升的地方,升层思考和升维思考真正明确提升部分。


7)定义指标,并能够对指标进行拆解,然后进行数学建模。


8)将抽象出来的能力诉求转换成技术挑战,此步对于技术人员来说相当于找到了靶子,可以进行方案的设计了,需要结合自底向上的架构推导方式。


9)创新可以是业务创新,也可以是产品创新,也可以是技术创新,也可以是运营创新,升层思考、升维思考,使用第一性原理思维、生物学(进化论–进化=变异+选择+隔离、熵增定律、分形和涌现)思维等哲科思维可以帮助我们在业务,产品,技术上发现不同的创新可能。可以说哲科思维是架构师的灵魂思维。


2、自底向上推导应用架构



先根据业务流程,分解出系统时序图,根据时序图开始对模块进行归纳,从而得到粒度更大的模块,模块的组合/聚合构建整个系统架构。


基本上应用逻辑架构的推导有 4 个子路径,他们分别是:


  • 业务概念架构:业务概念架构来自于业务概念模型和业务流程;

  • 系统模型:来自于业务概念模型;

  • 系统流程:来自业务流程;

  • 非功能性的系统支撑:来自对性能、稳定性、成本的需要。


效率、稳定性、性能是最影响逻辑架构落地成物理架构的三大主要因素,所以从逻辑架构到物理架构,一定需要先对效率、稳定性和性能做出明确的量化要求。


自底向上重度依赖于演绎和归纳。


如果是产品方案已经明确,程序员需要理解这个业务需求,并根据产品方案推导出架构,此时一般使用自底向上的方法,而领域建模就是这种自底向上的分析方法。


对于自底向上的分析方法,如果提炼一下关键词,会得到如下两个关键词:


1)演绎:演绎就是逻辑推导,越是底层的,越需要演绎:


  • 从用例到业务模型就属于演绎;

  • 从业务模型到系统模型也属于演绎;


根据目前的问题,推导出要实施某种稳定性措施,这是也是演绎。


2)归纳:这里的归纳是根据事物的某个维度来进行归类,越是高层的,越需要归纳:


  • 问题空间模块划分属于归纳;

  • 逻辑架构中有部分也属于归纳;


根据一堆稳定性问题,归纳出,事前,事中,事后都需要做对应的操作,是就是根据时间维度来进行归纳。


3、领域驱动设计架构


大部分传统架构都是基于领域模型分析架构,典型的领域实现模型设计可以参考 DDD(领域驱动设计),详细可以参考《实现领域驱动设计》这本书,另外《UML 和模式应用》在领域建模实操方面比较好,前者偏理论了解,后者便于落地实践。


领域划分设计步骤:


(1) 对用户需求场景分析,识别出业务全维度 Use Case。

用户头像

Java高工P7

关注

还未添加个人签名 2021.11.08 加入

还未添加个人简介

评论

发布
暂无评论
阿里P8级大神经验分享,怎样成为一个优秀的架构师?(1)