贾玉祥,昝红英
(郑州大学 计算机与人工智能学院,河南 郑州 450001)
软件体系结构(Software Architecture)又称软件架构,是指对系统进行推理所需的一组结构,包括软件元素及其之间的关系和二者的属性[1]。软件架构涵盖多种软件结构,大致分为3 类:静态结构、动态结构和分配(Allocation)结构。软件架构设计就是在需求分析的基础上对软件高层结构进行建模(通常使用UML 工具),以指导后续的详细设计等软件开发活动。
软件体系结构课程教学有一定难度[2-3],原因包括以下几个方面:①教学内容比较抽象,软件架构属于早期设计阶段,与编码实现阶段有一定距离,而学生对编码更熟悉,也更感兴趣;②软件架构关注的是软件质量属性,只有在复杂度较高的项目中才能体现价值,而学生接触到的项目多为课程设计类的小项目,且主要关注功能实现,不关心质量属性;③教材内容与业界主流技术脱节,案例缺少源码等配套资料,学生只能从用户的角度来分析软件架构。
近年来,高校在软件体系结构课程教学方面进行了一系列探索。文献[4]提出贯穿式案例实践教学法,设计一套可贯穿软件体系结构课程主要知识点的若干案例,组织学生分组实践,设计软件架构;文献[5]将高等教育心理学中的学习迁移理论应用于软件体系结构教学;文献[6]针对应用型本科院校,提出将软件体系结构课程教学内容整合为软件体系结构原理和软件体系结构设计两部分,并利用案例驱动教学;文献[7]从教学内容、课程实践项目、教学效果评估3 个方面探讨研究生软件体系结构课程建设方案;文献[8]提出将翻转课堂教学模式应用于软件体系结构课程教学,以任务驱动为主线,实现课程教学前、中、后3部曲操作。
引入开源项目[9-10]也是提高教学效果的一个有效手段,源码可以展现软件的静态结构,也可以通过部署、运行、调试,体现软件的动态结构。结合源码可以对软件架构有一个比较全面的了解,同时基于源码的架构恢复也是软件体系结构的一个研究方向[11-13]。因此,源码为软件体系结构教学与科研的结合提供了一个很好的切入点。
“案例+开源”将已有的案例教学法向前推进了一步,本文引入开源框架,提出“案例+开源+框架”教学法,除架构分析与设计外,进一步考虑了系统实现。基于框架的软件开发正是软件体系结构的价值体现[14],是构件层面的软件复用[15]。基于主流开源框架进行软件体系结构教学,既具有开源项目的优势,又能使学生掌握框架的使用方法,为将来从事软件开发工作打下一定基础。本文采用Java生态中最流行的开源框架Spring,将教学内容与Spring 案例相结合,探索基于开源框架的软件体系结构教学方法。
将软件体系结构与Spring 相结合的一些最新实践为本文教学方法提供了参考,《Software Architecture with Spring 5.0》[16]基于Spring 介绍了客户服务器(Client-Server,CS)架构、模型—视图—控制器(Model-View-Controller,MVC)架构、事件驱动架构、管道过滤器(Pipe-and-Filter)架构、微服务(Microservices)架构和无服务器(Serverless)架构共6 种架构风格。南京大学曹春教授[17]的软件体系结构课程结合Spring 讲授了基于构件的架构、分层架构、CS 架 构、MVC 架 构、RESTful(Representational State Transfer)架构、可扩展架构、管道过滤器架构、事件驱动架构、响应式(Reactive)架构、微服务架构、云计算架构及无服务器架构等10余种架构风格。
本课程面向软件工程、计算机科学与技术专业的高年级本科生,教学内容及学时安排如表1 所示。将课程理论与实践相结合,并安排讨论课进行学习实践结果的展示与验收,课程主要内容包括:概述、软件结构与视图、软件质量属性及策略、软件体系结构风格、软件体系结构设计与评估。概述部分介绍软件体系结构基本概念、软件体系结构的作用,并引入思政元素;软件结构与视图是软件架构的核心概念,是软件在不同视角下所呈现的模样;软件质量属性是软件架构的决定因素,每一种质量属性都有一定的架构策略;软件体系结构风格是课程的主体内容,会介绍不同风格的软件结构、质量属性表现、优缺点等内容,并结合Spring 进行实验和案例分析;软件体系结构设计与评估介绍属性驱动的软件体系结构设计方法(Attribute-Driven Design,ADD)以及基于场景的软件体系结构评估方法。课程一共有48 学时,其中实验环节16 个学时,软件质量属性及策略、软件体系结构风格两部分内容在主题选择上具有很好的弹性,可以根据不同学时安排灵活选择主题。
Table 1 Teaching contents and hour arrangement表1 教学内容及学时安排
(1)软件结构与视图。软件结构可分为静态结构、动态结构和分配结构。静态结构主要是模块(Module)结构,包括模块的分解与使用、模块的层次、类之间的结构、数据项之间的结构等;动态结构又称为构件—连接件(Component &Connector,C&C)结构,是软件运行时的结构,包括服务交互、进程/线程并发等;分配结构描述的是软件与周围环境的关系,如项目目录结构描述模块与文件的关系、部署结构描述软件与硬件的关系、分工结构描述模块与开发小组的关系等。
为软件结构建立的模型又称为视图(View)。要完整地呈现一个软件架构,往往需要多种结构对应的多个视图,即多视图模型。“4+1”视图模型分别从4 种不同涉众的角度,采用逻辑视图、开发视图、运行视图和部署视图来描述软件架构,最后用用例视图将不同视图统一起来,每个视图都可以用一种或多种UML 图形来描述。
(2)软件质量属性及策略。软件质量属性是描述软件质量好坏的指标,用来描述软件的非功能性需求。常见的质量属性指标有:可用性(Availability)、互操作性(Interoperability)、可修改性(Modifiability)、性能(Performance)、安全性(Security)、可测试性(Testability)及易用性(Usability)等,其中可用性、互操作性、性能、安全性、易用性为运行期质量属性,可修改性、可测试性为开发期质量属性。功能需求一般用用例(Usage Case)表示,而质量属性需求一般用场景(Scenario)表示,每一个质量属性都会有相应的策略保障需求达成,例如:大型网站性能相关策略有分库分表、读写分离、动静分离、缓存等,可用性相关策略有异地多活、服务降级、限流等。
(3)软件体系结构风格。软件无论大小都有架构,按照组成软件的元素及其交互方式不同,可把软件架构分为不同风格。分层风格是最常见的软件架构风格,对应软件的模块结构,3 层架构是常见的应用软件开发架构,根据构件与连接件的不同形成不同的架构风格;调用返回风格是过程之间的显式调用;事件驱动风格是基于消息机制的隐式调用;管道与过滤器风格由传输数据的管道与加工数据的过滤器构成;MVC 风格将模型与表示分离,并通过控制器进行交互,是Web 应用的常见风格;客户服务器风格的系统包括客户端和服务器两类构件,连接件采用“请求—响应”机制。浏览器服务器(Browser-Server,BS)架构可看作CS 架构的特例,为了提高系统之间的互操作性,提出面向服务的架构(Service Oriented Architecture,SOA)风格,系统之间的交互体现为服务的提供与消费,服务的注册、发现及使用均有标准化的协议。Web Service 是SOA 在Web 上的实现,采用WSDL、UDDI、SOAP等一系列基于XML 的标准。RESTful 风格把服务看作对资源的访问,采用HTTP 的GET、POST、PUT、DELETE 等操作访问资源,API 简洁明了,数据可以采用轻量、高效的JSON 形式。
Spring 是当前最流行且开源的Java 开发框架,其首先是一个控制反转(Inversion of Control,IOC)容器,负责管理对象的生命周期及对象之间的依赖关系,支持面向切面的编程(Aspect Oriented Programming,AOP)。Spring 为软件开发提供一站式解决方案,包括Web 框架SpringMVC、持久层框架Spring Data、云计算框架Spring Cloud 等,也可以很方便地集成第三方框架,可以很好地支持Web 应用、事件驱动、响应式系统、微服务、云计算、无服务器架构、批处理等软件系统开发。Spring Boot 的出现更是简化了基于Spring的开发过程,实现了基于构件的软件开发。
郑州大学软件工程、计算机科学与技术专业大四上学期开设了软件体系结构课程,本文对2018 级计算机科学与技术专业的本科生进行框架使用情况问卷调查,回收有效问卷166 份,结果如表2 所示。由表2 可知,超过40%的学生使用过Spring 框架,大约1/4 的学生使用过SpringMVC,超过1/3 的学生使用过Spring Boot,说明Spring 有一定群众基础,且需要进一步普及,适合与软件体系结构课程相结合。二者结合既有助于学生对软件体系结构知识的理解,又有助于对Spring的掌握与应用。
Table 2 Proportion of framework usage表2 框架使用比例 %
Spring 官网有一系列公开的学习资料,其中Spring guides 中的案例就是很好的入门材料。如表3 所示,Spring guides 中的案例根据复杂程度分为3 种类型:Getting started guides 案例一般学习用时15~30min;Topical guides 案例一般学习用时60min;Tutorial 案例一般学习用时2~3h。因此,可根据课程内容选择相应案例进行学习,如表4 所示。在学习一种架构风格时,可以基于Spring Boot 起步依赖从头实现一个案例,每种风格的程序依赖构件不尽相同,例如:MVC、RESTful 风格依赖于Spring Web,SOA 风格依赖于Spring Web 与Spring Web Services,而Pipe-and-Filter 风格依赖于Spring Batch。
基于Spring 的开源项目非常多,尤其是Web 应用。Spring 官方在Github 上也维护着一些学习案例,其中spring-petclinic 是一个很有影响的基于MVC 架构的Web数据管理系统(Petclinic-V1)。在此基础上,Spring petclinic community 给出了petclinic 其他架构风格的实现,包括MVC 架构的改进版本spring-framework-petclinic(Petclinic-V2)、RESTful 风格的版本spring-petclinic-rest(Petclinic-V3)以及微服务风格的版本spring-petclinic-microservices等。
Table 3 Spring guides cases表3 Spring guides案例
Table 4 Cases of different architecture styles表4 不同架构风格的案例
表5 给出了MVC 架构及RESTful 架构相关的3 个版本的比较。Petclinic-V2 比Petclinc-V1 增加了一个service层,项目目录结构与层次相对应且更加清晰,在数据持久化方面支持3 种持久化方案。在视图和基础框架方面,两个版本在Thymeleaf 与JSP、Spring Boot 与Spring framework之间作出了不同选择。Petclinic-V3 为RESTful 风格,实现了前后端分离,可以支持不同的前端实现,如angular、angularjs、react 等。结合源代码可以更细致地比较不同架构风格的区别,例如,对比MVC 可更清晰地看到RESTful 风格URL 的优点。
Table 5 Case comparison of different architecture styles表5 不同架构风格案例比较
基于现有的petclinic 源码,可以进一步完善功能、优化性能。在功能方面:①可以完善数据管理功能。系统对owner、pet、petType、visit、vet、specialty 等数据进行管理,未建立visit 与vet 的关联,未对vet 相关数据进行增删改处理,可对此进行完善;②可以增加用户角色,进行权限管理。在性能调优方面,则可以借鉴Julien Dubois 的调优实践进行性能监测,调整组件或策略进行性能优化。此部分内容可以作为软件质量属性中可修改性和性能方面相关策略的评估与实践。
学生在大学前3 年里已经独自开发或合作开发了一些软件系统,这些系统以Java Web 居多,学生对该类系统最为熟悉。因此,每人选择一个Java Web 系统,结合软件体系结构课程知识对系统进行架构分析,包括使用UML对软件结构进行建模,分析软件的质量属性(采用了哪些保障质量属性的策略,依据是什么?)与架构风格(采用了哪些架构风格,依据是什么?)。基于对软件架构的分析,使用Spring 对系统进行重构,MVC 架构采用SpringMVC(或替换Struts2),RESTful 架构采用SpringMVC(或替换CXF),持久层采用Spring Data JPA(或替换MyBatis)。学生对自己开发的项目非常熟悉,可以把更多精力放到基于构件的软件开发方法上,体会软件架构重用的价值。
在2021-2022 学年第一学期对2018 级计算机科学与技术专业的学生首次采用本文提出的教学方法(称为教改后),在2020-2021 学年第一学期对2017 级计算机科学与技术专业的学生采用“基于一个复杂案例”的教学方法(称为教改前)。学期末,学生通过学校教学质量管理平台填写调查问卷进行教学评价。教改前后评价结果如表6所示。
可见教改前此课程评分较低,低于同类课程的院系平均分和全校平均分。原因之一可能是课程采用的案例“基于移动互联网的速递物流跟踪系统”复杂度较高,包括前后端分离、后端Spring/Hibernate/CXF 框架、Android 端、Web端、扫码、定位、地图等技术,与大四上学期学生面临考研,没有足够的精力投入到课程中这一现实问题形成矛盾。
Table 6 Teaching evaluation scores by students before and after adopting the proposed teaching method表6 教改前后学生评教得分
与教改前相比,本文教学方法的评教得分提升了9.45个百分点,高于同类课程院系平均分3.09 个百分点,并高于同类课程全校平均分2.07 个百分点。学生评教具体指标如表7 所示,由此可见,本文提出的教学方法在所有指标上都高于同类课程院系平均分和全校平均分,尤其在课程资源、知识掌握、能力提升、素养提升等方面优势较为明显。这在一定程度上反映了基于开源框架的软件体系结构教学方法是可行、有效的。
本文针对软件体系结构课程内容抽象、落地难的问题,探索了基于开源框架的“案例+开源+框架”教学方法。在教学内容选择上突出实践性,引入主流框架技术;以软件质量属性策略、软件架构风格为纲组织内容,主题选择弹性强,可以灵活适应不同的学时安排;采用Spring 开源案例和教学资料锻炼学生基于源码分析软件架构的能力,同时锻炼基于构件的软件开发能力。一个学期的教学实践结果显示,采用本文提出的教学方法后,学生参与课程的积极性更高,学习效果也得到了提高。下一步将在突出课程实践性的同时,兼顾知识体系的完整性与均衡性,加强软件体系结构设计相关内容的学习,并增加大型系统常用的软件中间件技术。
Table 7 Metrics of teaching evaluation by students表7 学生评教指标