架构 架构原则 软件架构 原则
2022-04-22 15:58:39 12 举报
AI智能生成
架构原则,软件设计
作者其他创作
大纲/内容
面向对象设计原则 (SOLID)<br>
SRP 单一职责原则<br> (The Single Responsibility Principle)
修改某个类的理由应该只有一个,如果超过一个,说明类承担不止一<br>个职责,要视情况拆分。
OCP 开放封闭原则 <br>(The Open Closed Principle)
软件实体应该对扩展开放,对修改封闭。一般不要直接修改类库源码<br>(即使你有源代码),通过继承等方式扩展。
LSP 里氏替代原则 <br>(The Liskov Substitution Principle)
任何超类出现的地方都可以替换为它的一个子类的实例。这样,它们<br>之间才是真正的 is-a 关系。
ISP 接口分离原则 <br>(The Interface Segregation Principle)
不要强迫用户去依赖它们不使用的接口。换句话说,使用多个专门的<br>接口比使用单一的大而全接口要好。
DIP 依赖倒置原则 <br>(The Dependency Inversion Principle)
高层模块不应该依赖于底层模块,二者都应该依赖于抽象。换句话说<br>,依赖于抽象,不要依赖于具体实现。
接口设计原则
接口标准化原则
架构设计中,模块之间的接口设计应该尽量采用业界标准协议和公司内部协议规范,<br>以保持稳定性和兼容性。如果涉及对外的互操作等则建议采用用业界标准协议。
接口扩展性原则
接口设计要具有良好的可扩展性,比如通过预留字段等方式以方便今后的扩展。
接口兼容性原则
系列化接口中所有版本应该保持兼容性,其基础通用功能和关键特性接口(如软件升级)<br>设计在一个系列版本之内必须保持兼容,如:1.x系列、2.x系列
接口抽象性原则
接口设计要具有抽象性,接口定义应该强调接口的逻辑语义而不是实现方法,以屏蔽掉具体<br>实现的差异。
分布式系统设计理论
CAP理论<br>
一致性 (Consistency)
一致性指“all nodes see the same data at the same time”,即更新操作成功,<br>所有节点在同一时间的数据完全一致。
可用性 (Availability)
可用性指“Reads and writes always succeed”,即服务一直可用,而且响应时间正常。
分区容错性 (Partition tolerance)
分区容错性指“the system continue to operate despite arbitrary message loss or failure of part of the system.”,<br>即分布式系统在遇到某节点或网络分区故障时,仍然能够对外提供满足一致性和可用性的服务。<br>
BASE理论
基本可用 (Basically Available)
基本可用是指分布式系统在出现故障时,允许损失部分可用性,即保证核心可用。比如服务降级。
软状态 (Soft State)
软状态是指允许系统存在中间状态,而该中间状态不会影响系统的整<br>体可用性。分布式存储中一般一份数据至少存三个副本,允许不同节<br>点间副本同步的延迟就是软状态的体现。
最终一致性 (Eventual Consistency)
最终一致性是指系统中的所有数据副本经过一段时间后,最终能够达<br>成一致状态。弱一致性和强一致性相反,最终一致性是弱一致性的一<br>种特殊情况。
康威法则<br>Conway's Law
指出组织架构和系统架构之间有一种隐含的映射关系:<br> Organization which design system […] are constrained to produce designs which are copies of the communication structures of these organization. 设计系统的组织其产生的设计等价于组织间的沟通结构。
分布式系统设计原则
N + 1 设计
部署的线上系统永远不要少于两个,通常为三个。比方说无状态的 <br>Web/API 一般部署至少>=2 个。
回滚设计
确保系统可以回滚到以前发布过的任何版本。可以通过发布系统保留<br>历史版本,或者代码中引入动态开关切换机制 (Feature Switch)。
禁用设计
能够关闭任何发布的功能。新功能隐藏在动态开关机制 (Feature Switch) <br>后面,可以按需一键打开,如发现问题随时关闭禁用。
监控设计
在设计阶段就必须考虑监控,而不是在实施完毕之后补充。例如在需求<br>阶段就要考虑关键指标监控项,这就是度量驱动开发 (Metrics Driven Development) <br>的理念。
设计多活数据中心
不要被一个数据中心的解决方案把自己限制住。当然也要考虑成本和公司规模发展阶段。
使用成熟的技术
只用确实好用的技术。商业组织毕竟不是研究机构,技术要落地实用<br>,成熟的技术一般坑都被踩平了,新技术在完全成熟前一般需要踩坑躺坑。<br>
异步设计
能异步尽量用异步,只有当绝对必要或者无法异步时,才使用同步调用。<br>
无状态系统
尽可能无状态,只有当业务确实需要,才使用状态。无状态系统易于<br>扩展,有状态系统不易扩展且状态复杂时更易出错。<br>
水平扩展而非垂直升级
永远不要依赖更大、更快的系统。一般公司成长到一定阶段普遍经历过买<br>更大、更快系统的阶段,即使淘宝当年也买小型机扛流量,后来扛不住才<br>体会这样做不 scalable,所以才有后来的去 IOE 行动。
设计时至少要有两步前瞻性
在扩展性问题发生前考虑好下一步的行动计划。架构师的价值就体现<br>在这里,架构设计对于流量的增长要有提前量。
非核心则购买
如果不是你最擅长,也提供不了差异化的竞争优势则直接购买。避免 <br>Not Invented Here 症状,避免凡事都要重造轮子,毕竟达成业务目标才是重点。
使用商品化硬件
在大多数情况下,便宜的就是最好的。这点和第 9 点是一致的,通过<br>商品化硬件水平扩展,而不是买更大、更快的系统。
小构建、小发布和快试错
全部研发要小构建,不断迭代,让系统不断成长。这个和微服务理念一致。
隔离故障
实现故障隔离设计,通过断路保护避免故障传播和交叉影响。通过<br>舱壁泳道等机制隔离失败单元 (Failure Unit),一个单元的失败不至<br>影响其它单元的正常工作。<br>
自动化
设计和构建自动化的过程。如果机器可以做,就不要依赖于人。自动化是 DevOps 的基础。
系统架构设计原则
领域视角原则
架构师必须要有领域工程意识,必须站在领域的角度,从多行业、多<br>产品应用构成的领域维度来规划和设计架构。输出的系统架构设计,<br>要能从“面”上回答解决了哪些问题,而不仅仅只是回答“点”上的问题。
系统视角原则
"架构师必须要有系统工程意识,架构设计必须站在全系统的角度,对整<br>个系统进行宏观整体把握,不能把软件/硬件等割裂开来,只考虑某一个<br>方面。另一方面,系统设计中各个方面的能力应该是均衡的,没有明显<br>的瓶颈和短木板。<br><br>架构师在回答架构设计支撑了那些系统功能问题的同时,需要回答做了哪<br>些平衡,为什么做这些平衡?"
重用原则
"重用分为几个层次:架构重用、组件重用、设计重用、代码重用。<br>领域架构设计强调的是领域内架构的重用和基于架构的组件重用。<br>架构重用包括:逻辑架构重用和物理架构重用,在可能的情况下要<br>尽量扩大重用的范围,特别是物理架构的重用,将带来巨大的价值。<br><br>设计师在进行系统设计和实现时必须遵循重用原则,应用开发时,<br>如果已有领域架构和平台,则其系统设计必须符合领域架构,并应<br>用平台组件开发;如果无领域架构和平台,则需要考虑如何构建领<br>域架构和平台为后续类似产品的重用和共享做好准备。 "
商业目标原则
由于影响架构设计的各个质量属性之间存在一定的联系和冲突,比如:<br>高的性能需求会导致成本的上升,高的可靠性要求也会导致成本的上<br>升,扩展性的提高可能会牺牲一定的性能,而可移植性好则会提升架<br>构的可重用性等等。因此架构设计时必须对各个质量属性的进行权衡,<br>而权衡的依据就是架构设计的商业目标,包括:目标市场、架构的应<br>用范围、上市时间、成本和收益、关键需求(质量属性需求)、开发<br>过程和约束等,只有确定了商业目标才能确定架构设计的方向并对各<br>个相互冲突的质量属性进行仲裁和权衡。
一致性原则
架构设计应该作为一个统一的整体而存在,架构设计在整体应该上<br>是统一、和谐的,符合美学原则。<br><br>架构中类似需求应该遵循相同的设计规范和标准,比如:接口、模<br>型、术语等。<br><br>架构中类似的处理机制应该是统一的:如异常处理流程。而可测试<br>性、可调试性等设计等应采用统一的框架设计和实现。
够用/简单原则(JUST RIGHT)
在达到预定的目标、具备所需要的功能前提下,架构设计应尽量简单<br>,避免“过度设计”,这样可减少处理费用,提高系统效益,便于实现和<br>管理。<br><br>简化「组件、模块、方法、类」的功能设计,避免设计面面俱到的<br>「多功能组件、模块、方法、类」;调用功能时,避免功能过剩。<br>架构设计应该在适当的范围内考虑其可扩展性,特别需要杜绝为了<br>应用某种新技术而采用新的架构。
变化点分离原则
领域架构设计的核心就是通过设计支持各个变化点独立变化,因此在<br>需求分析阶段就需要分离公共的部分和变化的部分,判断出哪些需求<br>是相对稳定不变的,哪些需求是可能变动的,并将不同的变化点分离<br>开;在逻辑架构设计时,工作重点也是使变化点在逻辑上隔离,并确<br>定支持变化点的机制。根据那些稳定不变的需求设计体系结构,而根<br>据那些可变的需求设计软件的“可扩展性”。<br><br>分面和分层都是识别并隔离变化点的方法,使得架构具有良好的可扩<br>展性。<br>a. 首先要确认软件中变和不变的因素,并根据变化频度进行分类。<br>b. 依据变化频度的分类进行层次划分,并标出各个层次的依赖关系。<br>c. 对不变的部分,设计得稳固、牢靠。对变化的部分,根据变化的频<br>度设计其灵活性。"
逻辑与物理分离原则
系统功能逻辑与基于质量、成本等因素分割的物理实现并不存在直接<br>的对应关系,同样的系统可能由于硬件技术和软件技术的需要,在功<br>能部署和实现手段都会发生变化。架构设计强调多视角的设计,逻辑<br>和物理分离就是在变化点分离原则的基础上,把逻辑功能和物理实现<br>进行分离,在接口设计上就是把逻辑语义和接口形式以及物理承载分<br>离开。
支持分阶段交付原则
对于大型需求的设计,需要在架构设计时考虑要能够支持平台和产品<br>分阶段/增量式实现和交付的要求,具有较强的可修改性和可扩展性。<br>分阶段交付的版本之间要保持兼容性。
子系统设计原则
高内聚/低耦合原则
子系统/模块的划分必须具有独立性,将联系比较密切、功能近似的<br>部分集中,使得子系统/模块的内部功能、信息等各方面的凝聚性较<br>好。<br><br>子系统/模块之间的联系要尽量减少,接口设计简单、明确,尽量减<br>少子系统/模块相互之间各种不必要的数据、调用和控制联系。一个<br>内部联系强的子系统/模块对外部的联系必然是相对很少的。
数据冗余最小原则
架构设计应该使得系统中数据的冗余最小,否则可能引起相关的功能<br>数据分布在各个不同的子系统/模块中,大量的原始数据需要调用和同<br>步,大量的中间结果需要保存和传递,大量计算工作将要重复进行。<br>数据冗余使得程序结构紊乱,不但给软件开发工作带来很大的困难,而<br>且系统的工作效率和可靠性也大大降低了。
数据一致性原则
为了提高系统性能,备份节点和子系统/模块必要时需要对数据进行缓<br>存,当发生变化时,必须有相应的机制保证缓存数据的一致性和有效性。
通用的平面划分原则
划分平面是隔离架构中变化点的常用方法。<br>平面划分作为最高层次的系统划分,目的首先自然是进行功能的分类、分解,<br>以及对系统复杂性分割、封装。平面划分的另一个目的是对系统设计所涉及<br>知识领域的划分,或者说是工作的划分,便于让不同知识领域的专家专心于<br>自己的领域开展下一步的设计工作。"
通用的层次划分原则
划分层次也是隔离架构中变化点的常用方法。分层的目的是要实现可重用性、<br>可更改性和可移植性。<br><br>层次结构是一种应用非常广的架构模式。操作系统、数据库管理系统和网络<br>通信软件都是层次结构软件系统的例子。<br><br>对于追求屏蔽作用(屏蔽变化)的系统,首先需要把通用的部分和可变的部<br>分分开。当通用部分和可变部分无法简单划分时,就需要一个抽象分析的过<br>程。越是抽象的东西越不容易发生变化,越是具体的东西越是容易变化。
分层的单向依赖原则
采用分层模式时,原则上只允许较高层次依赖于较低层次,不允许出现反向依赖。
无循环依赖原则
架构设计中,子系统/模块之间的依赖关系要尽量减少,且不允许模块之间出现循环依赖。
避免跨层通信原则
采用分层模式时,原则上不允许出现跨层通信,包括:API调用、消息通信等。
解耦原则
解耦原则要求架构设计中的各个模块之间是松耦合的,并且各个组件<br>可以基于架构独立应用,这也是架构可裁减性的实现基础。
实现无关性原则
构成架构的元素DM是与实现无关的,这也正是架构能够重用的关键。
灵活部署原则
架构设计要能够支持各模块灵活部署。构成架构的模块的粒度划分<br>需要考虑不同应用场景的部署需求,同时各模块也是与实现无关的,<br>其部署可以是灵活的,与物理位置无关。
质量属性设计原则
可重用性原则
架构或基于此架构的某些组件能够在未来的产品应用开发中能够重复使用。<br>这要求架构设计时要充分分析其应用场景、范围和实现技术,以及不同的质量属性。
可扩展性原则
可扩展性是通过变更系统增加新功能的能力和容易程度,架构设计根据其规<br>模和复杂性对可扩展性有不同的要求。<br><br>稳定性和可扩展性之间存在辩证的关系:如果架构不可扩展的话,那么就没<br>有发展前途,所以不能只关心稳定性而忽视可扩展性;“可扩展”的前提条件<br>是“保持架构稳定”,否则相同难以按计划开发出来,稳定性是使系统能够持<br>续发展的基础。
可修改性原则
基于该架构产品及平台的可修改性(Modifiability) ,是与系统架构关系最为密切的一个质量属性。<br>1. 基于领域架构的产品能够进行快速修改,修改代价低,架构不限制组件设计及局部设计的修改。<br>2. 对外接口稳定,对内接口:机制稳定、可演进、可扩充。<br>3. 领域架构本身具有自我扩展性。<br>分层是一种通用的可修改性实现方法,通过分层,可以使得修改被限制在各层之内,各层的修改不<br>会影响其他层次的设计和实现。
可移植性原则
架构设计不依赖于特定的运行环境,基于该架构的产品及平台具有能够在不同软件<br>或(和)硬件环境下运行的能力。如果对任何特定运行环境的所有假设都仅包含其<br>中一个组件(或者在最坏情况下,包含在少数几个易于修改的组件)中,则该架构<br>是可移植的。一般通过分层模式来提高架构的可移植性,在架构中对平台相关实现<br>细节的封装表现为可移植性层。
兼容性原则
架构设计上要支持不同应用场景以及系列化版本之间的兼容性设计。<br>兼容性有两个方面的含义:一是版本的前向(forward)和后向(backward)兼容,<br>另一个是对运行环境的兼容性。运行环境包括软件环境(如OS)、硬件环境(如硬件平台)<br>和网络环境(如接口兼容性)等,运行环境的兼容性要求与可移植性要求是相同的。<br>后向兼容是兼容老版本,前向兼容是指将来可以被新版本所兼容,所以前向兼容本质<br>上是特殊的可扩展性需求。
可伸缩性原则
架构设计在不同的应用场景下具有一定的可伸缩性,包括容量、规格等指标。<br>在线扩容能力就是一种可伸缩性,当用户增长时,可以通过增加服务器、<br>虚拟机、Docker容器等不同级别的手段来适应。
可裁剪性原则
可裁剪性是指用户从系统中删除部分功能的难易程度,或者从系统中<br>选择部分功能丢弃其他功能的难易程度。可裁剪性有利于提高架构的可重用性。<br><br>架构和平台设计必须具有良好的可裁剪性,可裁减性可以看成是可配置<br>性的一个方面。可裁减性设计要求尽量降低组件之间的耦合和依赖关系。
性能原则
架构设计必须满足预定的性能目标,做好性能、成本、可扩展性和可移植性<br>等的综合权衡,并能够根据应用场景的变化具有平滑扩容的能力。<br><br>性能需求主要包括两个方面,<br>一是吞吐量(Throughput),指系统或部件在指定时间段内执行的工作量,<br>二是响应时间或速度,指事务或请求与响应之间的平均延迟。 <br><br>系统性能还包括:容量(Capacity);资源占用率(Resource Consumption),<br>如内存资源的使用效率,CPU资源占用率;Memory footprint,是指程序被加载<br>到内存中所占用的静态内存大小。
可用性/可靠性原则
架构设计要满足预定的可靠性/可用性指标。不同的应用场景对可靠性指标的要求是不同的。<br>系统的可靠性指系统硬件和软件在运行过程中抵抗异常情况的干扰及保证系统正常工作的能力。<br>衡量系统可靠性的指标是平均故障间隔时间和平均维护时间。前者指平均的前后两次发生故障<br>的时间,反映了系统安全运行时间,后者指故障后平均每次所用的修复时间,反映系统可维护性的好坏。
安全性原则
架构设计必须满足目标应用场景的安全需求。<br>安全性是衡量系统在向合法用户提供服务的同时,阻止非授权用户使用的能力,以及防止<br>意外或恶意访问限制性的资源或大量的资源,试图显示数据、改变/删除数据、访问系统<br>服务、降低系统的可用性。
可测试性/可调试性原则
架构设计必须具有良好的可测试性和可调试性。<br>良好的可测试性/可调试性能够方便系统缺陷的发现,降低对工具、仪器种类和专业<br>测试设备和仪器的要求,并且在发现问题后能够快速检测和定位故障。<br>设计中应该统一考虑可测试性/可调试性框架的设计和实现,尽量减少测试软件和产<br>品软件之间的耦合性。
可生产性/可制造性原则
略。
可安装性原则
可安装性是指完成设备安装的难易程度。针对用户安装使用场景,是否有针对性设计来提高系统可安装性。
可配置性原则
架构设计上提供,能够方便地支持组件的裁剪和配置。
成本原则
架构设计要从全局出发,不能只考虑单方面的成本,要综合考虑软件、硬件、整机、<br>生产、备货、发货、测试等各个方面,以达到系统的最优成本。
易懂性原则
"好的架构设计必然是易于理解,易于掌握的,同时符合自然原则和美学原理。<br>良好的易懂性同时也有利于提高系统的可维护性。"
欢迎点赞~👍
0 条评论
下一页