软件架构与设计模式

软件架构与设计模式的区别

有很多程序员经常会把软件架构和设计模式混淆,比如认为MVC架构是一种设计模式。实际上它们是完全不同的概念软件。软件架构通常考虑的是代码重用,而设计模式考虑的是设计重用,应用框架则介于两者之间,部分代码重用,部分设计重用,有时分析也可重用。在软件开发过程中有以下3种级别的重用。

(1)内部重用:即在同一应用程序中将公共使用的抽象块进行重复使用。

(2)代码重用:即将通用模块组合成库或工具集,以便在多个应用和领域都能使用。

(3)架构重用:即为专用领域提供通用的或现成的基础结构,以获得最高级别的重用性。

软件架构设计模式虽然相似,但却有着根本的不同。设计模式是对在某种环境中反复出现的问题及解决该问题的方案的描述,它比软件架构更抽象;软件架构可以用代码表示,也能直接执行或复用,而对设计模式而言,只有实例才能用代码表示。设计模式是比软件架构更小的元素,一个软件架构中往往含有一个或多个设计模式,软件架构总是针对某一特定应用领域,但同一设计模式却可适用于各种应用。可以说,软件架构是应用程序,而设计模式是开发应用程序的具体方法。我们经常使用的软件架构有MVC架构、ORM架构等。

三层架构

通常意义上的三层架构(3-Tier Architecture)是将整个业务应用自下而上划分为数据访问层(Data Access Layer,DAL)、业务逻辑层(Business Logic Layer,BLL)和表示层(User Interface Layer,UI)。区分层次是为了体现“高聚合、低耦合”的设计理念。在软件体系架构设计中,分层式结构是最常见、也是最重要的一种结构。

三层架构的编程模型

三层架构的编程模型如下

软件架构和设计模式-LMLPHP

在这3个层次中,系统主要功能和业务逻辑都在业务逻辑层进行处理。

1.表示层

​表示层又叫作表现层,位于三层架构的最上层,与用户直接接触,主要是B/S信息系统中的Web浏览页面。作为Web浏览页面,表示层的主要功能是实现系统数据的传入与输出,在此过程中不需要借助逻辑判断操作就可以将数据传送到业务逻辑层进行数据处理,处理后会将结果反馈到表示层中。换句话说,表示层实现用户界面功能,将用户的需求传达和反馈,并用业务逻辑层或者Models进行调试,保证用户体验。

2.业务逻辑层

​业务逻辑层的功能是对具体问题进行逻辑判断与执行操作,接收到表示层的用户指令后,会连接数据访问层。业务逻辑层在三层架构中位于表示层与数据访问层的中间位置,也是表示层与数据访问层的桥梁,实现三层之间的数据连接和指令传达,可以对接收数据进行逻辑处理,实现数据的修改、获取、删除等功能,并将处理结果反馈到表示层中,实现软件功能。

3.数据访问层

​数据访问层是数据库的主要操控系统,实现数据的增加、删除、修改、查询等操作,并将操作结果反馈到业务逻辑层。在实际运行过程中,数据访问层没有逻辑判断能力,为了实现代码编写的严谨性,提高代码阅读程度,一般软件开发人员会在该层编写SQL语句,保证数据访问层的数据处理功能。

三层架构的优缺点

(1)有利于系统的分散开发,每一层都可以由不同的人员来开发,只要遵循接口标准,利用相同的对象模型实体类就可以,这样可以大大提高系统的开发速度。

(2)可以很容易地用新的实现来替换原有层次的实现,有利于标准化。

(3)有利于各层逻辑的代码复用,降低层与层之间的依赖。

(4)避免了表示层直接访问数据访问层,表示层只与业务逻辑层有联系,提高了数据安全性。

(5)方便系统的移植,如果要把一个C/S系统变成B/S系统,只要修改三层架构的表示层就可以。业务逻辑层和数据访问层几乎不用修改就可以轻松地把系统移植到网络上。

(6)项目结构更清楚,分工更明确,极大地降低了后期维护成本,减少了维护时间。

(1)降低了系统的性能,这是不言而喻的。如果不采用分层式结构,则很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成。

(2)有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,则可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。

(3)增加了开发成本。

ORM架构

ORMObject Relational Mapping,对象关系映射)是一种为了解决面向对象与关系型数据库存在的互不匹配的现象的技术。简单地说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系型数据库中。实现持久化比较简单的方案是采用硬编码方式,为每一种可能的数据库访问操作都提供单独的方法,这个操作是在三层架构中的数据访问层完成的。因此,ORM架构就是专门为数据操作层设计的。

ORM架构的编程模型

ORM架构的编程模型如下图所示。

软件架构和设计模式-LMLPHP

ORM的方法论基于4个核心原则。

(1)简单:ORM以最基本的形式建模数据。比如ORM会将MySQL的一张表映射成一个Java类(模型),表的字段就是这个类的成员变量。

(2)精确:ORM使所有的MySQL数据表都按照统一的标准精确地映射成Java类,使系统在代码层面保持准确统一。

(3)易懂:ORM使数据库结构文档化。比如MySQL数据库就被ORM转换成了Java程序员可以读懂的Java类,Java程序员可以只把注意力放在他擅长的Java层面(当然能够熟练掌握MySQL更好)。

(4)易用:ORM包含对持久化对象进行CRUD操作的API,例如,创建create()、更新update()、保存save()、加载load()、查找find()等,也就是将SQL查询全部封装成了编程语言中的函数,通过函数的链式组合生成最终的SQL语句。通过这种封装,避免了不规范、冗余、风格不统一的SQL语句,可以避免很多人为Bug,方便编码风格的统一。目前市面上采用ORM架构的经典框架有MyBatisJPA、Hibernate等。

ORM的优缺点

(1)提高开发效率,降低开发成本。

(2)使开发更加对象化。

(3)可移植。

(4)可以很方便地引入数据缓存之类的附加功能。

(1)自动化进行关系型数据库的映射需要消耗系统性能。其实这里的性能消耗比较小,一般来说可以忽略。

(2)当处理多表联查、where条件复杂之类的查询时,ORM的语法会变得复杂。

MVC架构

MVC的全称是Model View Controller,是模型(Model)-视图(View)-控制器(Controller)的缩写。它指导我们用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特地发展起来,用于把传统的输入、处理和输出功能映射在一个逻辑的图形化用户界面的结构中。

编程模型

MVC架构提供了一种对HTMLCSSJavaScript等前端代码完全隔离的编程方式。各模块之间分工明确,职责清晰,下面对MVC的模块进行详细介绍。

(1)模型层用于处理应用程序数据逻辑的部分,负责在数据库中存取数据。

(2)视图层用于处理数据显示的部分,通常视图是根据模型数据来渲染的。

(3)控制层用于处理用户交互的部分,负责从视图读取数据,控制用户输入,并向模型发送数据。

三层之间主要的交互流程如下图所示。

软件架构和设计模式-LMLPHP

目前市面上采用MVC架构的主流应用框架有Spring MVC、JSF、JFinal等。

MVC的优缺点

(1)降低耦合性。视图层和业务层分离,这样就允许更改视图层代码而不用重新编译模型和控制器代码。同样,一个应用的业务流程或者业务规则的改变只需要改动MVC的模型层即可。因为模型与控制器和视图相分离,所以很容易改变应用程序的数据层和业务规则。(2)提高代码重用性。随着IT技术的不断升级,需要用越来越多的方式访问应用程序。MVC模式允许使用各种不同样式的视图来访问同一个服务端的代码,因为多个视图能共享一个模型。由于模型返回的数据没有进行格式化,所以同样的构件能被不同的界面使用。

(3)软件生命周期内的维护成本降低,因为采用MVC使开发和维护用户接口的技术含量降低,分离视图层和业务逻辑层也使得Web应用更易于维护和修改。

(4)部署更快,使用MVC使开发时间得到相当大的缩减,它使Java开发人员把精力集中于业务逻辑,界面开发人员把精力集中于表现形式。

(5)有利于代码工程化管理,由于不同的层各司其职,每一层不同的应用都具有某些相同的特征,有利于通过工程化、工具化管理程序代码。控制器也提供了一个好处,就是可以使用控制器来连接不同的模型和视图去完成用户的需求,这样控制器可以为构造应用程序提供强有力的手段。给定一些可重用的模型和视图,控制器可以根据用户的需求选择模型进行处理,然后选择视图将处理结果显示给用户。

(1)没有明确的边界定义。作为初学者完全理解MVC并不是很容易。使用MVC需要精心的设计,由于它的内部原理比较复杂,所以需要花费一些时间去思考。同时由于模型和视图要严格分离,给调试应用程序带来了一定困难。每个构件在使用之前都需要经过彻底的测试。(2)不适合小型、中等规模的开发。因为开发人员需要花费大量时间理解MVC的设计理念,将MVC应用到规模并不是很大的应用程序通常会得不偿失。

(3)增加系统结构和实现的复杂性。对于本来就很简单的界面,如果严格遵循MVC,使模型、视图与控制器分离,则会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率。

(4)视图与控制器之间过于紧密的连接。虽然视图与控制器从设计上是相互分离的,但从逻辑上看却是联系紧密的部件。如果视图没有控制器的存在,则形同虚设,反之亦然,这样就使得视图和控制器的代码不能独立重用。

(5)降低了视图对模型数据的访问效率。根据模型操作接口的不同,视图可能需要多次调用才能获得足够的显示数据。对未变化数据不必要的频繁访问,会降低操作性能。

RPC架构

RPC(Remote Procedure Call,远程过程调用)是建立在Socket通信上的设计。在一台机器上运行的主程序,可以调用另一台机器上准备好的子程序,就像LPC(Local Procedure Call,本地过程调用)。也就是说两台服务器A和B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在同一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。

RPC架构的编程模型

RPC架构主要分为3个部分,如下图所示。

(1)服务端(Provider):运行在服务端,提供服务接口定义与服务实现类。

(2)注册中心(Registry):运行在服务端,负责将本地服务发布成远程服务,管理远程服务,提供给服务消费者使用。

(3)消费端(Consumer):运行在客户端,通过远程代理对象调用远程服务。

软件架构和设计模式-LMLPHP

在上图中,服务端启动后主动向注册中心注册机器IP、端口及提供的服务列表;消费端启动时由注册中心获取服务端提供方的地址列表。目前,使用RPC架构的开源框架非常多,举例如下。

(1)应用级相关的服务框架:阿里的Dubbo/DubboxGoogle GRPCSpringBoot/Spring Cloud

(2)远程通信相关的协议:RMI、Socket、SOAP(HTTP XML)、REST(HTTPJSON)

(3)通信相关的框架:MinaNetty

RPC优缺点

(1)提升系统的可扩展性。

(2)提升系统的可维护性和持续交付能力。

(3)实现系统高可用。

(1)一个完善的RPC``架构的框架开发难度大。

(2)RPC架构的框架调用成功率受限于网络状况。

(3)调用远程方法对初学者来说难度大。

未来架构演变之路

随着越来越多的人参与到互联网,曾经的单体应用架构越来越无法满足需求,因此,分布式集群架构出现了。也因此,分布式搭建开发成为Web开发者必须掌握的技能之一。这些技术包含但不限于ZooKeeperDubbo、消息队列(ActiveMQ、Kafka、RabbitMQ)、NoSQL(Redis、MongoDB)Nginx、分库分表MyCatNetty等。分布式架构建立在RPC架构的基础之上。大概很多小伙伴都见过下图,这是在Dubbo官网中找到的一张描述项目架构演进过程的图。

分布式架构建立在RPC架构的基础之上。大概很多小伙伴都见过下图,这是在Dubbo官网中找到的一张描述项目架构演进过程的图。

软件架构和设计模式-LMLPHP

​它描述了每一种架构需要的具体配置和组织形态。当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少节点部署和成本,我们通常会采用单一应用架构。之后才出现了ORM架构,该架构大大简化了增删改查的操作流程,提高了开发者的工作效率。

​随着用户量增加,访问量逐渐增大,单一应用增加机器带来的加速度越来越小,我们需要将应用拆分成互不干扰的几个应用以提升效率,于是就出现了垂直应用架构。MVC架构就是一种非常经典的用于加速前端页面开发的架构。

​当垂直应用越来越多时,应用之间的交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速地响应多变的市场需求,于是就出现了分布式服务架构。分布式架构下服务数量逐渐增加,为了提高管理效率,RPC架构应运而生。RPC架构用于提高业务复用及整合,在分布式服务架构下,RPC架构是关键。

​下一代架构,将会是流动计算架构占据主流。当服务越来越多时,容量的评估、小服务的资源浪费等问题逐渐明显。此时,需要增加一个调度中心,基于访问压力实时管理集群容量,提高集群利用率。SOA(Service-Oriented Architecture,面向服务的架构)架构就是用于提高集群利用率的。在资源调度和治理中心方面,SOA架构是关键。

05-23 10:53