一、场景
某软件公司为其新推出的字处理软件设计了一种脚本语言,专门用于开发该字处理软件的附加功能插件。为了提高该语言的编程效率,公司组织软件工具开发部门为脚本语言研制一套集成开发环境。软件工具开发部门根据字处理软件的特点,对集成开发环境进行了需求分析,总结出以下3项核心需求:
(1)集成开发环境需要提供对脚本语言的编辑、语法检查、解释、执行和调试等功能的支持,并要实现各种功能的灵活组合、配置与替换。
(2)集成开发环境需要提供一组可视化的编程界面,用户通过对界面元素拖拽和代码填充的方式就可以完成功能插件核心业务流程的编写与组织。
(3)在代码调试功能方面,集成开发环境需要实现在脚本语言编辑界面中的代码自动定位功能。具体来说,在调试过程中,编辑界面需要响应调试断点命中事件,并自动跳转到当前断点处所对应的代码。
针对上述需求,软件工具开发部门对集成开发环境的架构进行分析与设计,王工认为该集成开发环境应该采用管道-过滤器的架构风格实现,李工则认为该集成开发环境应该采用以数据存储为中心的架构风格来实现。公司组织专家对王工和李工的方案进行了评审,最终采用了李工的方案。
二、问题
2.1、问题1
请用200字以内的文字解释什么是软件架构风格,并从集成开发环境与用户的交互方式、集成开发环境的扩展性、集成开发环境的数据管理三个方面说明为什么最终采用了李工的设计方案。
2.2、问题2
在对软件系统架构进行设计时,要对架构需求进行分析,针对特定需求选择最为合适的架构风格,因此实际的软件系统通常会混合多种软件架构风格。请对核心需求进行分析,说明为了满足需求(2)和(3),分别应采用何种架构风格,并概要说明采用相应架构风格后的架构设计过程。
三、解析
3.1、问题1
需要背:软件架构风格是指描述特定软件系统组织方式的惯用模式。组织方式描述了系统的组成构件和这些构件组织方式,惯用模式则反映众多系统共有的结构和语义。
管道-过滤器风格:
① 形象比喻:自来水处理厂的流水线。
② 工作方式:水(数据)从进水口进来,经过沉淀池(过滤器1),再流到消毒池(过滤器2),最后流出。
③ 缺点:一旦开闸,很难干预。水流到一半,就很难把水抽出来放回到源头了。而且管道的口径必须一致(通常只能传递简单的字符流)。
以数据存储为中心:
① 形象比喻:教室里的黑板,或者在线共享文档。
② 工作方式:黑板在中间(中央数据仓库)。老师,学生(各种功能插件)围着黑板看。谁想写就写,谁想擦就擦,通过黑板交互信息。
③ 优点:互动性强,有一个人修改信息大家都能实时看到。数据结构复杂,黑板上可以支持图,表,公式等等,不限于字符流。
3.1.1、交互方式
IDE是程序员写代码的工具。需要一边编写代码的时候,一边能够实时的提示报错来告诉开发者怎么修正代码。并且写完独立的一段代码之后可以随时运行。
管道风格:必须所有代码全部写完之后,执行一次所有代码的检查,运行等等操作。中间无法实时交互,所有的问题都留在最后,排查和解决问题的难度非常大。
黑板风格:修改了代码之后,检查插件可以实时检测到并且提示错误,这样就实现了高频交互。独立一块代码可以执行之后,调试插件也可以独立运行这一块来提高运行频率,也实现了高频交互。
3.1.2、扩展性
对IDE要求是功能的灵活组合,配置和替换。
管道风格:像接水管一样,如果要在中间加一个过滤器,需要把水管锯断,加完之后需要保证新水管和老水管的接口必须一样。
黑板风格:如果想要新增一个功能插件,可以直接获取黑板里的数据,不用影响到现有的结构。按需增加,很自由。
3.1.3、数据管理
对IDE的要求是支持脚本,语法树,可视化模型,调试信息。
管道风格:擅长传简单的字符流。复杂的语法树需要反复打包解包,很不方便。
黑板风格:中央数据库天生就支持复杂结构。大家直接读取对象,不用转来转去。
3.2、问题2
3.2.1、需求(2)
可视化编程(拖拽生成代码)
① 场景理解:用户通过拖拽的方式,完成代码的编写,实现插件功能。
② 通俗理解:像是两个不同国家的人交流,A说中文(界面化组件),B说英文(代码),需要一个翻译官把每句话实时翻译成另一种语言才能执行。
③ 匹配架构:解释器风格。
④ 架构设计过程:
1)定义语言:规定好每种组件代表什么意思,比如线条是什么意思,方框是什么意思。这一步就是定义语法和语义。
2)写翻译官:做一个解释器引擎,专门读懂这些定义好的组件。
3)执行:解释器读组件,然后生成或者执行对应的代码。
3.2.2、需求(3)
调试与断点(代码自动定位)
① 场景理解:代码运行过程中,遇到断点,编辑器立刻中断,光标停留在断点行。
② 通俗理解:代码引擎和编辑器界面是两个独立的,引擎不能直接管理编辑器界面,引擎通过广播事件的方式通知自己遇到断点,然后编辑器界面订阅引擎的广播消息,再查询断点位置,最后跳转过去。
③ 匹配架构:隐式调用风格,也叫事件驱动风格。
④ 设计过程:
1)首先定义事件:定义一个叫【断点命中】事件。
2)注册表:创建一个【通讯录】,界面告诉通讯录,如果发生【断点命中】,来喊我。
3)触发和响应:引擎遇到断点------》触发事件------》系统查询通讯录------》自动调用界面的定位函数。
四、答案
【问题1】 软件架构风格是指描述特定软件系统组织方式的惯用模式。组织方式描述了系统的组成构件和这些构件的组织方式,惯用模式则反映众多系统共有的结构和语义。
从集成开发环境与用户的交互方式看,用户通常采用交互式的方式对脚本语言进行编辑、解释执行与调试。在这种情况下,采用以数据存储为中心的架构风格能很好地支持交互式数据处理,而管道-过滤器架构风格则对用户的交互式数据处理支持有限。
从集成开发环境的扩展性来看,系统核心需求要求实现各种编辑、语法检查、解释执行等功能的灵活组织、配置与替换。在这种情况下,采用以数据存储为中心的架构风格,以数据格式解耦各种功能之间的依赖关系,并可以灵活定义功能之间的逻辑顺序。管道-过滤器架构风格同样以数据格式解耦数据处理过程之间的依赖关系,但其在数据处理逻辑关系的灵活定义方面较差。
从集成开发环境的数据管理来看,集成开发环境需要支持脚本语言、语法树(用于检查语法错误)、可视化模型、调试信息等多种数据类型,并需要支持数据格式的转换。以数据存储为中心的架构将数据存储在统一的中心存储器中,中心存储器能够表示多种数据格式,并能够为数据格式转换提供各种支持。管道-过滤器架构风格通常只能支持有限度的数据格式,并且在数据格式转换方面的灵活性较差。
【问题2】 为了满足需求(2),应该采用解释器架构风格。具体来说,需要:① 为可视化编程元素及其拖拽关系定义某种语言,并描述其语法与语义;② 编写解释器对该语言进行解释;③ 生成对应的脚本语言程序。
为了满足需求(3),应该采用隐式调用架构风格。具体来说,首先需要定义"断点在调试过程中命中"这一事件,并实现当断点命中后的屏幕定位函数。集成开发环境维护一个事件注册表结构,将该事件与屏幕定位函数关联起来形成注册表中的一个记录项。在调试过程中,集成开发环境负责监听各种事件,当"断点在调试过程中命中"这一事件发生时,集成开发环境查找事件注册表,找到并调用屏幕定位函数,从而实现脚本语言编辑界面与调试代码的自动定位。