抽象和关注点分离

抽象和关注点分离


Abstraction 抽象 #

当考虑某一问题的模块化解决方案时,可以给出许多抽象级。

  • 在最高的抽象级上,使用问题所处环境的语言以概括性的术语描述解决方案(例如,用户故事);
  • 在较低的抽象级上,将提供更详细的解决方案说明;
  • 当陈述一种解决方案时,面向问题的术语和面向实现的术语会同时使用(例如,用例);
  • 最后,在最低的抽象级上,以一种能直接实现的方式陈述解决方案(例如,伪代码)。

在开发不同层次的抽象时,软件设计师力图创建过程抽象数据抽象

  • 过程抽象是指具有明确和有限功能的指令序列。“过程抽象”这一命名暗示了这些功能,但隐藏了具体的细节。过程抽象的例子是在 SafeHome 系统中针对摄像机的词“使用”,“使用”隐含了一长串的过程步骤(例如,在移动设备上激活 SafeHome 系统,登录到 SafeHome 系统,选择要预览到摄像机,在移动 App 用户界面上找到摄像机控件等)。
  • 数据抽象是描述数据对象的命名数据集合。在过程抽象“使用”的场景下,我们可以定一个名为 camera 的数据抽象。同任何数据对象一样,camera 的数据抽象将包含一组描述摄像机的属性(例如,摄像机编号、位置、视野、平移角度、缩放)。因此,过程抽象“使用”将利用数据抽象camera的属性所包含的信息。

关注点分离 #

关注点分离是一个设计概念,它表明任何复杂问题如果被分解为可以独立解决或优化的若干块,该复杂问题便能够更容易地得到处理。

关注点是一个特征或一个行为,被指定为软件需求模型的一部份。将关注点分割为更小的关注点(由此产生更多可管理的块),便可用更少的工作量和时间解决一个问题。

分而治之 #

分而治之是一种策略,把一个复杂问题分解为若干可管理的块来求解。因为,两个问题被结合到一起的认知复杂度经常要高于每个问题各自的认知复杂度之和。

模块化 #

模块化是关注点分离的最常见的表现。软件被划分为独立命名的、可处理的组件,有时被称为模块,把这些组件集成到一起可以满足问题的需求。

在进行模块化时,应避免使用太少的模块或太多的模块

  • 如果无限制划分软件,那么开发软件所需的工作量将会小到忽略不计!不幸的是,其他因素开始起作用,导致这个结论是不成立的。随着模块总数的增加,开发单个软件模块的工作量(成本)趋于降低。
  • 给定同样的需求,程序中模块更多意味着每个模块的规模更小。然而,随着模块数量的增加,集成模块的工作量(成本)也在增加。
  • 事实上,的确存在一个模块数量M,这个数量可以带来最小的开发成本。但是我们缺乏成熟的技术来精确地预测M

模块化设计(以及由其产生的程序) 使开发工作更易于规划,可以定义和交付软件增量,更容易实施变更,能够更有效地开展测试和调试,可以进行长期维护而没有严重的副作用。

信息隐蔽 #

模块化概念面临的一个基本问题是:“应当如何分解一个软件解决方案以获得更好的模块集合?”

信息隐蔽原则提出模块应该“具有的特征是:每个模块对其他所有模块都隐蔽自己的设计决策”。换句话说,模块应该被特别说明并设计,使信息(算法和数据) 都包含在模块内,其他模块无须对这些信息进行访问。

隐蔽的含义是,通过定义一系列独立的模块得到有效的模块化,独立模块之间只交流实现软件功能所必须的信息

  • 抽象有助于定义构成软件的过程(或信息)实体;
  • 隐蔽定义并加强了对模块内过程细节的访问约束以及对模块所使用的任何局部数据结构的访问约束。

功能独立 #

功能独立的概念是关注点分离、模块化、抽象和信息隐蔽的直接产物。

通过开发具有“专一”功能和“避免”与其他模块过多交互的模块,可以实现功能独立。换句话说,软件设计时应使每个模块仅涉及需求的某个特定子集,并且当从程序结构的其他部分观察时,每个模块只有一个简单的接口。

独立性为什么如此重要

  • 具有有效模块化(也就是独立模块)的软件更容易开发,这是因为功能被分隔而且接口被简化(考虑由一个团队开发时的结果);
  • 独立模块更容易维护(和测试),因为修改设计或修改代码所引起的副作用被限制,减少了错误扩散,而且模块复用也成为可能。
  • 概括地说,功能独立时良好设计的关键,而设计又是软件质量的关键

独立性可以通过两条定性的标准进行评估:内聚性和耦合性

  • 内聚性显示了某个模块相关功能的强度;
  • 耦合性显示了模块间的相互依赖性。

内聚性 #

内聚性是信息隐蔽概念的自然扩展。一个内聚的模块执行一个独立的任务,与程序的其他部分组件只需要很少的交互简单地说,一个内聚的模块应该只完成一件事情(理想情况下)。即使我们总是争取高内聚性(即专一性),一个软件组件执行多项功能也经常是必要的和可取的。然而,为了实现良好的设计,应该避免“分裂型”组件(执行多个无关功能的模块)。

耦合性 #

耦合性表明软件结构中多个模块之间的相互连接。耦合性依赖于模块之间的接口复杂性、引入或进入模块所在的点以及什么数据通过接口进行传递。在软件设计中,应当尽力得到最低可能的耦合。模块间简单的连接性使得软件易于理解,并且不太可能将一个模块中发现的错误传播到其他系统模块中。

求精 #

逐步求精是一种自顶向下的设计策略。连续细化过程细节层是开发应用的一个好方法,通过逐步分解功能的宏观陈述(过程抽象)进行层次开发,直至最终达到程序设计语言的语句这一级。

求精是一个细化的过程。该过程从高抽象级上定义的功能陈述(或信息描述)开始。也就是说,该陈述概念性地描述了功能或信息,但是没有提供有关功能内部的工作或信息内部的结构。可以在原始陈述上进行细化,随着每次细化的持续进行,将提供越来越多的细节。

抽象和细化是互补的概念

  • 抽象能够明确说明内部过程和数据,但对“外部使用者”隐藏了低层细节;
  • 细化有助于在设计过程中揭示低层细节;
  • 这两个概念均有助于设计人员在设计演化中构建出完整的设计模型

参考资料 #

  1. 《软件工程 - 实践者的研究方法》
© 2024 lyremelody.cn All Rights Reserved
访问量: