概要
说明
在探讨 “架构设计方法” 之前,我们需要先搞清楚一个问题:如何评判架构设计的优劣?
在软件工程中,我们以一个标准来评价软件设计的质量:高内聚、低耦合。
这个标准主要用于评判子系统、模块或类的内聚性高低,以及耦合度的高低。
因此,下面将围绕设计一个"高内聚低耦合"的系统为目标,来探讨架构设计该怎么做。
由于,架构设计的理论有很多,每个人的理解程度也不尽相同,下面我选取了几个最为常用的指导原则,结合个人的经验和总结来与大家进行探讨。
顶层架构设计原则
顶层架构设计原则,侧重决策和选择,是权衡利弊的思维方式。
合适原则
- 核心思想
- 满足当前业务的架构,才是最好的架构。
- 常见误区
- 当前资源:没有那么多人,却想干那么多活。
- 过度设计:没有那么大的业务场景,却想着一步到位。
- 技术情怀:为了技术而技术,不考虑实际业务需求。
- 说明
- 结合当前人力、条件、业务等各种约束设计出来的架构,才能合理地将资源整合在一起并发挥出最大功效。
- 小结
- 合适优于优秀。
简单原则
- 核心思想
- 架构越简单越稳定,越复杂越容易出问题。
- 常见误区
- 整体复杂:只关注局部,而忽略了整体
- 使用复杂:只关注提供能力,而忽略了用户体验
- 说明
- 架构应该保持简单和易于理解,避免过度复杂的设计和依赖。
- 简单性有助于提高开发、维护和调试的效率,减少潜在的错误和风险。
- Tips:谨记KISS原则(Keep It Simple, Stupid)
- 小结
- 简单优于复杂。
演进原则
- 核心思想
- 架构是在业务变化中不断完善的。
- 常见误区
- 步子太大:希望一口吃成个大胖子
- 难以扩展:没有做好预测和规划,不能灵活的应对变化
- 说明
- 对于软件来说,变化才是主题。
- 软件架构,需要根据业务发展不断的变化。
- 因此,软件架构要先满足当前业务,做好预测和规划,在业务变化中不断完善。
- Tips:架构设计时要时刻提醒自己,不要贪大求全,盲目采用大公司的做法。应认真分析当前的业务特性,明确主要问题,设计合理的方案,然后在运行中不断随着业务进行演化。
- 小结
- 演进优于一步到位。
小结
一个良好的架构设计是怎样的?
- 1)满足现有需求和解决现有问题,符合团队和技术能力水平。(合适原则)
- 2)架构先简单设计,再不断迭代优化,如此进度和风险都可控。(简单原则)
- 3)具有一定前瞻性,但不要过度设计,从迭代中持续演进和完善。(演进原则)
通用架构设计原则
通用架构设计原则,侧重落地和执行,是较为具体的手段。
冗余原则
- 核心思想
- 避免单点,保证系统的稳定性。
- 说明
- 永远不要少于两个,通常为三个。
- 常见技术
- 冗余设计,如节点、副本、主从等
扩展原则
- 核心思想
- 拥抱变化,保证系统的可扩展性。
- 说明
- 前瞻性和预见性。
- 预见可能的问题和潜在的风险,采取相应的预防和应对措施。
- 设计着眼于未来,未来总比预想的快。(走一步看二步想三步)
- 常见技术
- 配置化、接口、抽象类、拦截器等
- SPI、插件化、集群化、多副本、多分区等
抽象原则(拆分)
- 核心思想
- 发现规律,将复杂的问题简单化。
- 说明
- 将大问题分解成小问题,降低认知复杂度,提高办事效率。
- Tips:抽象能力是是我们技术同学最重要的能力之一。
- 常见技术
- 分层、模块化、拆分、设计模式等
隔离原则
- 核心思想
- 职责分离,避免业务之间的互相影响。
- 说明
- 隔离不同维度的职责,保证每个维度的职责都是高内聚的。
- 职责分离最大的挑战是:一个职责到底要划分到多细,没有量化的标准。
- 常见技术
- 读写分离、资源隔离、服务拆分、变与不变分离等
小结
哪个原则最能体现架构师的价值?为什么?
- 架构设计它难在哪里?难在应对变化或不确定性。
- 所以这里我的选择是扩展原则或演进原则。因为它是一种预见性的架构设计原则。
- 预见性是指一个人对事物发展的预判和前瞻,一个人预见性的强弱往往决定着一个人的能力大小。
开发设计原则
单一职责原则(SRP)
- 核心思想:一个类只做一件事情。
- 说明
- SRP,全称 Single Responsibility Principle
- 单一职责,意味着,高内聚,低耦合,只有一个原因会引起变化。
- 职责过多,意味着,相互依赖,相互影响,可能有多个原因引起变化,容易牵一发而动全身。
开放封闭原则(开闭原则)(OCP)
- 核心思想:对扩展开放,对修改封闭。
- 说明
- OCP,全称 Open-Closed Principle
- 要求类不作修改而能够扩展功能,体现了类的封装与继承。
- 应面向抽象编程,不应该面向具体编程,因为抽象相对稳定。
里氏替换原则(LSP)
- 核心思想:子类必须能够替换其基类。
- 说明
- LSP,全称 Liskov Substitution Prinicple
- 对继承机制的约束规范,只有子类能够替换基类,才能保证继承复用是可靠地。
- 强调的子类替换父类后程序运行时的正确性,它用来帮助实现开闭原则。
最少知识原则(迪米特法则)(LKP)
- 核心思想:一个类对自己依赖的类知道的越少越好。
- 说明
- LKP,全称 Least Knowledge Principle
- 被依赖的类,向外公开的方法应该尽可能的少。
- 服务提供方,向外公开的方法,越少越好。
接口隔离原则(ISP)
- 核心思想:使用多个小而精的接口,而不要使用一个大的总接口。
- 说明
- ISP,全称 Interface Segregation Principle
- 简而言之,接口应该是内聚的,应该避免“胖”接口。
- 接口隔离,强调接口的单一性,避免接口彼此污染。
依赖倒置原则(DIP)
- 核心思想:抽象不依赖于具体,具体依赖于抽象。
- 说明
- DIP,全称 Dependece Inversion Principle
- 高层模块不依赖于底层模块,二者都同依赖于抽象。
- 应该面向接口编程,不应该面向实现类编程。
小结
以上就是6个基本的面向对象设计原则,它们就像面向对象程序设计中的金科玉律,遵守它们可以使我们的代码更加鲜活,易于复用,易于拓展,灵活优雅。
“你并不必严格遵守这些原则,违背它们也不会被处以刑罚。但你应当把这些原则看做警铃,若违背了其中的一条,那么警铃就会响起。”
那么,作为一名架构师我们应该具备什么能力呢?
深入理解业务,拥有全局视野,选择合适的技术,解决关键问题,并指导研发落地实施 。
最后
在实际工作中,我们应以业务需求为导向,根据时间、资源和团队状况,做出权衡和决策。这对于构建一个好的架构设计来说至关重要。
架构设计系列文章
- 架构设计系列:什么是架构设计
- 架构设计系列:几个常用的架构设计原则
- 架构设计系列:高并发系统的设计目标
- 架构设计系列:如何设计可扩展架构
- 架构设计系列:如何设计高性能架构
- 架构设计系列:如何设计高可用架构
- 架构设计系列:如何应对软件变化
- 架构设计系列:常用设计模式的实践