1、架构设计的目的是什么?
架构设计的目的主要是为了解决复杂度带来的问题
1.1、编程范式
其实所谓架构就是限制,限制源码放在哪里、限制依赖、限制通信的方式,但这些限制比较上层。编程范式是最基础的限制,它限制我们的控制流和数据流:结构化编程限制了控制权的直接转移,面向对象编程限制了控制权的间接转移,函数式编程限制了赋值,相信你看到这里一定一脸懵逼,啥叫控制权的直接转移,啥叫控制权的间接转移,不要着急,后边详细讲解。
这三个编程范式最近的一个也有半个世纪的历史了,半个世纪以来没有提出新的编程范式,以后可能也不会了。因为编程范式的意义在于限制,限制了控制权转移限制了数据赋值,其他也没啥可限制的了。很有意思的是,这三个编程范式提出的时间顺序可能与大家的直觉相反,从前到后的顺序为:函数式编程(1936年)、面向对象编程(1966年)、结构化编程(1968年)。
在非面向对象的编程语言中,我们如何在互相解耦的组件间实现函数调用?答案是函数指针。通过函数指针进行组件间通信的方式非常脆弱,工程师必须严格按照约定初始化函数指针,并严格地按照约定来调用这些指针,只要一个人没有遵守约定,整个程序都会产生极其难以跟踪和消除的 Bug。所以面向对象编程限制了函数指针的使用,通过接口-实现、抽象类-继承等多态的方式来替代。
目前要让一个软件系统完全没有可变变量是不现实的,但是我们可以通过将需要修改状态的部分和不需要修改的部分分隔成单独的组件,在不需要修改状态的组件中使用函数式编程,提高系统的稳定性和效率。
没有结构化编程,程序就无法从一块块可证伪的逻辑搭建,没有面向对象编程,跨越组件边界会是一个非常麻烦而危险的过程,而函数式编程,让组件更加高效而稳定。没有编程范式,架构设计将无从谈起。
2、那么复杂度的来源于哪里?
1)高性能
2)高可用:本质上是通过冗余来实现高可用
3)高可扩展性:为了应对将来需求变化的一种能力,需要预测变化。如何应对变化(提炼出变化层和稳定层,提炼出一个抽象层和实现层,类似装饰者模式)
4)低成本:只有创新才能达成低成本的目标
5)安全
6)规模:复杂度是量变引起质变,功能越来越多,导致系统的复杂度指数级上升。
3、架构设计
3.1、原则
1)合适原则
2)简单原则
3)演化原则
HART,以人为本(设计的本质事社交),推迟决策(推迟不确定的决策),善于借鉴(所有设计都是在已有设计基础上的重新设计和调整创新),化虚为实(让想法具体化、有形化,以便于沟通交流)。
3.2、设计原则
设计原则有很多,我们进行架构设计的主导原则是 OCP(开闭原则),在类和代码的层级上有:SRP(单一职责原则)、LSP(里氏替换原则)、ISP(接口隔离原则)、DIP(依赖反转原则);在组件的层级上有:REP(复用、发布等同原则)、 CCP(共同闭包原则)、CRP(共同复用原则)
处理组件依赖问题的三原则:无依赖环原则、稳定依赖原则、稳定抽象原则。
3.3、整洁之道
依赖关系:越是中心,软件层次越高,外圆是机制,内圆是策略:源码中的依赖关系,必须指向同心圆的内层,即由底层机制指向高层
依赖就很好处理了:依赖关系与数据流控制流脱钩,而与组件所在层次挂钩,始终从低层次指向高层次,如下图。越具体的策略处在的层级越低,越插件化。切换数据库是框架驱动层的事情,接口适配器完全无感知,切换展示器是接口适配器层面的事情,用例完全无感知,而切换用例也不会影响到业务实体。
如果要设计一个便于推进各项工作的系统,那么其策略应该是在系统设计过程中尽可能多的保留可选项
架构师必须要是一线程序员,不经历设计的痛苦不可能成为优秀的设计师
架构设计因子:开发、部署、运行、维护
开发的团队,应该要和架构的设计保持一致
架构的设计,应该要考虑部署,易于部署,以及难部署的时候的其他设计方案
运行性要求也会影响架构设计,而且应该可视化架构的运行过程,让人可易于了解架构
维护有两个成本,“探秘”,“风险”
探秘是指修改系统的时候,找到最佳修改位置,所需要的理解成本
风险,是修改系统后,所可能因为出其他新的问题
策略与细节分离:设备无关性,保留更多的可选项
策略是指业务逻辑,以及操作过程,是体现系统的真正价值所在
细节是不会影响策略本身的行为,例如:数据库、访问方式、磁盘IO、框架、交互协议
https://www.cnblogs.com/iCanhua/p/15877594.html
4、架构设计流程
1)有的放矢---识别复杂度,看看上述复杂度的来源是什么质量属性?如功能耦合严重,根据业务、技术、团队进行排序
4.2、按图索骥---设计备选方案,3~5个
4.2.1、按照类图、序列图、组件图、部署图、用例图、状态图、活动图来画出相关的设计方案,进行对比灵活运用
---参考P68,《架构师的自我修炼》
3)深思熟虑---评选和选择备选方案,安装上述质量属性指标和设计原则选择
4)精雕细琢---详细方案设计
5、可扩展模式
5.1、按照不同思路拆分系统
1)面向流程拆分,将整个业务拆分不同阶段,分层架构,如TCP/IP模型,如展示层、业务层、数据层、存储层
2)面向服务拆分,将系统提供的服务拆分,SOA(面向服务的架构)、微服务,例如注册、登录、信息管理、安全设置等
3)面向功能拆分,每个服务的进一步细分,微内核架构
5.2、分层架构
1)层层传递,层与层之间边界清晰
5.3、微服务
1)微服务数量不易划分过多
2)3个人负责一个服务,符合下面人员的匹配划分
3)拆分方法,基于业务逻辑拆分,基于可扩展拆分(稳定服务、变动服务),基于可靠性拆分(将可靠性要求高的服务)。基于性能拆分
5.4、微内核(插件化架构)
1)分为核心系统和插件模块
6、框架模式
4.1、分层模式
4.2、适配器模式
适配器模式是一种结构型设计模式。适配器模式的思想是:把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
用电器来打个比喻:有一个电器的插头是三脚的,而现有的插座是两孔的,要使插头插上插座,我们需要一个插头转换器,这个转换器即是适配器。JAVA设计模式——适配器模式_LW_Fung的博客-CSDN博客_适配器模式
适配器模式涉及3个角色:
源(Adaptee):需要被适配的对象或类型,相当于插头。
适配器(Adapter):连接目标和源的中间对象,相当于插头转换器。
目标(Target):期待得到的目标,相当于插座。
适配器模式包括3种形式:类适配器模式、对象适配器模式、接口适配器模式(或又称作缺省适配器模式)。
4.3、管道过滤器模式
4.4、面向服务架构模式
4.5、发布订阅模式(GUI的OSD刷新)
4.6、共享数据模式
4.7、多层模式
4.8、能力中心模式
4.9、简单工厂模式
缺点师新增产品需要修改工厂,工厂类的职责相对过重,不易于扩展复杂的产品结构,违背开闭原则。
7、识别业务发展的趋势是什么?
业务的复杂度来源是什么?不同阶段不一样,业务扩展,稳定性还是易用性
产品类业务是技术推动业务发展
集中力量解决核心任务
8、开源库选择原则
1)聚焦是否满足业务
2)聚焦是否成熟
3)聚焦运维能力
9、参考书籍
《从零开始学架构》
《架构师的自我修炼》
《架构师修炼之道》
《架构整洁之道》