使用变异性建模和设计模式进行自适应系统工程:在智能家居中的应用
摘要
适应性对于许多系统而言正变得越来越重要,特别是对于那些部署在动态变化环境中的系统。其目的是让系统能够自主地响应并适应执行条件的变化,而无需人工干预。由于存在大量的变体决策(例如用户需求、环境特征)以及当前可复用的适应性专业知识的缺乏,构建一个在其生命周期中满足所有可能出现的需求和约束的系统变得愈发困难。本文提出了一种在多个抽象层次上为自适应系统开发策略的方法。该方法是首个将可变性与特征模型、可重用性与设计模式相结合,形成统一的产品派生解决方案的方法,从而有力支持以模块化方式开发自适应系统。我们通过基于智能家居场景的用例验证了所提出方法的可行性。
关键词 :自适应系统;设计模式;软件变异性;模块化;可重用性。
1 引言
自适应是许多系统的重要且理想属性,尤其对于那些部署在动态变化环境中的系统。尽管适应性可以使系统更具鲁棒性,但其构建却是一个具有挑战性的工程问题(Hellerstein 等,2004)。这类系统的关键要素是反馈控制环(FCL),它为自适应提供了通用机制(Hellerstein 等,2004)。然而,自适应系统的开发涉及大量与用户需求、系统的特定属性以及环境特征相关的变体决策。此外,目前缺乏可从一个适应系统迁移到另一个系统的可复用的适应性专业知识,这进一步增加了开发的难度和成本。
一种以模块化方式对自适应系统进行建模的方法是将可变性(Clements 和 Northrop,2003)(由特征建模定义)与可重用性(Gamma 等人,1995;Ramirez 和 Cheng,2009)(由设计模式定义)结合到一个统一的解决方案中。设计模式为常见的系统开发问题提供了灵活的解决方案,它表达在特定上下文中已知且反复出现的问题的解决方法。除了设计模式外,可变性管理还能够通过组合一组不同的核心资产来派生出多种产品,其表现形式为变异点。变异点表示基于软件的系统中的某个特定位置,在该位置做出决策以表达所选的变体(Svahnberg 等人,2005)。可变性的一个重要挑战在于提供描述和实现软件产品共性与变异性的解决方案。本文提出的方法的核心思想是捕获与 FCL 相关联的共性,并对与设计模式(Gamma 等人,1995;Ramirez 和 Cheng,2009)相关的变异性进行建模。
与依赖代码驱动方法的框架(Adamczyk 等,2008;Asadollahi 等,2009;Garlan 等,2004)和中间件平台(Floch 等,2006;Romero 等,2010;Rouvoy 等,2008)(参见第3节)不同,我们提出采用一种基于模型的方法 1 产品派生 2 组件复用。我们的方法是首个实现自适应系统中可变性与可重用性相结合的方法。随后定义了两个主要阶段:在领域工程阶段进行面向重用的开发,以及在应用工程阶段进行基于重用的开发。第一阶段通过开发与变异性规则相关联的核心资产,来生成可重用的自适应软件。第二阶段则利用设计模式的专业知识,构建满足用户需求的特定系统,该阶段基于领域工程的结果。可变性与可重用性的结合可分为三个层次:第一个层次在领域设计的领域工程阶段中定义,用于选择适当的模式;第二个层次在同一阶段的模式域中体现,用于通过模式选择系统的适当结构;第三个结合层次在应用工程阶段通过系统重构模式来实现,用于选择合适的配置。
因此,我们的方法首先通过使用设计模式和可变性管理来实现FCL的可重用性,然后展示了如何以模块化方式显式地建模FCL及其结构。我们使用一个智能家居场景来验证我们的方法。
本文的其余部分组织如下。第2节介绍了我们提议的动机和挑战。第3节介绍了一些相关工作。第4节定义了构建模块化自适应系统的方法。第5节细化了自适应系统中监控组件的设计,第6节介绍了其他组件及其相互关系的建模。在第7节中,我们通过一个智能家居系统案例研究来展示该方法的可行性。第8节对我们的方法进行了评估。最后,第9节总结全文并讨论了一些未来工作。
2 动机和挑战
在本节中,我们讨论了选择将可变性管理与设计模式结合用于建模自适应系统的原因。随后,我们描述了本方案需要面对的挑战。
2.1 动机
设计自适应系统的一种常见方法是使用提供通用机制以建模自适应的FCLs。这些 FCLs需要收集有关系统当前状态的信息,分析这些信息以诊断性能问题或检测故障,决策如何解决问题,并对这些决策采取行动(Cheng et al., 2009)。为了说明我们的观点,我们引入智能家居作为一种自适应系统。智能家居是指配备有一组计算实体的房屋,例如用于收集物理信息的传感器(如灯光、恒温器等)以及用于改变环境状态的执行器(如打开窗户、启用警报等)(Rashid 等,2011)。智能家居系统提供高层级功能,其中多个传感器和执行器协同工作以实现节能、气候控制和安全。该系统始终为其用户提供舒适、安全、能源效率(低运营成本)和便利。在分析阶段提出的智能家居功能模型允许创建不同的有效产品实例(图1)。在分析阶段,识别出高层目标和需求。然而,该系统的设计涉及大量与用户需求相关的变体决策。此外,FCL为建模该系统提供了一个良好的起点,但并未提供关于如何利用当前可复用的适应性专业知识的详细信息,而这些知识可以在不同FCL之间共享。
因此,关于FCL工程的以下研究问题变得尤为重要。具体而言,我们可以提及:
- 可复用的适应性专业知识如何在工程过程中使用?
- 我们如何在FCL的建模中选择可复用的适应性专业知识?
- 我们如何组合可复用的适应性专业知识来建模FCL?
2.2 挑战
在设计自适应系统之前,必须明确回答并解决上述问题。本文提出将可变性与设计模式结合到一个统一的解决方案中,以支持通过模块化方式开发自适应系统的产物派生。然后,我们必须面对若干挑战。
C1 支持结构变异性
主要困难在于处理广泛的结构变异性。这种可变性涵盖了用于建模自适应系统的组件的多样性,是由用户需求以及系统的特定属性等变体决策所导致的。
C2 显式建模反馈环
第二个挑战是如何对FCLs及其结构进行显式建模。
C3 确保自适应系统中组件的模块化和可重用性
最后一个挑战涉及缺乏可在不同适应系统之间复用的适应性专业知识。
3 相关工作
近年来,自适应软件系统工程领域的研究提出了多种方法:框架 [如 Rainbow (Garlan 等,2004)、StarMX (Asadollahi 等,2009) 和 AMT (Adamczyk 等,2008)], 中间件平台 [如 MADAM (Floch 等,2006)、MUSIC (Rouvoy 等,2008) 和 CAPPUCINO (Romero 等,2010)], 以及基于模型的技术 [如 EUREMA (Vogel 和 Giese,2014)、CASE (Luckey 和 Engels,2013) 和 Genie (Bencomo 和 Blair,2009)]。本节回顾了研究人员为促进基于模型的技术中结合设计模式与可变性管理来开发自适应软件系统所开展的部分代表性工作。
3.1 设计模式与适应
Ramirez(2008)以及 Ramirez 和 Cheng(2009,2010)提出了多个用于开发自适应系统的模式。这些模式被划分为自适应系统的三个关键要素:监控、决策和重构。它们有助于将功能逻辑与适应性逻辑分离开发。作者提出了一些模式,用于在较高抽象层次上描述自适应系统。Gomaa(2011)和 Gomaa 和 Hussein(2004)提出了一些模式,用于描述软件架构的动态行为(主从架构、集中式、客户端/服务器和去中心化架构)。这些模式对实现动态适应系统的开发者具有帮助作用。此外,它们仅支持某些类型的软件架构(如集中式和客户端/服务器架构)。
Mannava 和 Ramesh(2012)提出了现有设计模式的组合,用于实现自主计算系统的自我优化和自愈特性。作者提出了一种基于组件和面向对象软件工程的架构。该架构包含两个层:第一层处理内存管理,第二层则根据客户端的需求组合新的组件或新的Web服务。在 Chowdhury 和 Katchabaw(2012a,2013,2012b)中,Chowdhury 和 Katchabaw 从自适应系统文献(Ramirez,2008;Ramirez 和 Cheng,2009,2010)中引入了四个设计模式的集合,以实现游戏中的适应能力,并探讨了所提出模式在自动动态难度中的应用。
3.2 可变性管理与适应
在 Esfahani 等人 (2013) 中,提出了一种基于面向特征和在线学习的自适应软件系统工程方法。面向特征的方法用于表示工程师对适应选择的知识。此外,在线学习方法用于评估和推理适应决策。在 Bencomo 等人 (2008) 和 Bencomo 和 Blair (2009) 中,提出了一种称为 Genie 的方法。该方法使用模型驱动工程方法来支持自适应软件系统的开发。此外,他们使用模型来规范和生成基于中间件的软件制品。Genie 基于架构模型,以支持为基于组件的中间件技术生成和执行自适应系统。
Elkhodary 等人 (2009) 提出了一种名为 FUSION 的框架。作者描述了特性在其所开发的自适应框架中的作用。这些特性能够表示工程师关于系统某些方面的知识,可用于增强适应逻辑。此外,它们还可作为抽象手段,用于应对底层架构模型、分析算法和实现平台的异构性。
如前所述,构建自适应系统的研究工作有两种类型。其中一些使用设计模式来建模系统,而另一些则基于可变性管理。
拉米雷斯(2008)以及拉米雷斯和程(2009, 2010)或Gomaa(2011)和 Gomaa与Hussein(2004)提出的模式(在我们的工作中称为逻辑模式)并未提供将这些模式组合到工程过程中的解决方案。此外,拉米雷斯和程未提供这些模式的行为。然而,Gomaa等人提出的模式仅适用于特定架构。而在我们的方法中,我们提出了一种选择满足用户需求的模式的方法。
Chowdhury 和 Katchabaw (2012a, 2013, 2012b) 的工作或 Mannava 和 Ramesh (2012) 的工作使用了 Ramirez(2008)、Ramirez 和 Cheng (2009, 2010) 提出的模式,以定义构建自适应系统的技术。然而,一方面,Mannava 和 Ramesh(2012)的工作专门用于建模自我优化和自愈系统;Chowdhury 和 Katchabaw (2012a, 2013, 2012b) 的工作则专门用于建模视频游戏中的自动动态难度。另一方面,这些方法不支持通过可变性管理来选择模式。而我们的工作则允许通过选择设计模式来进行可变性管理,以满足诸如用户需求和系统的特定属性等变体决策。
关于支持自适应的可变性管理,Esfahani 等人 (2013) 或 Elkhodary 等人 (2009) 提出的方法并未提供一种解决方案,用以展示如何在更低的抽象层次上设计适应的不同组件。此外,Esfahani 等人 (2013) 的工作专门针对在线学习。然而,我们提出了一种通用模型,可用于设计各种类型的自适应系统。Bencomo 等人 (2008) 以及 Bencomo 和 Blair (2009) 的工作未提供一种方法来重用系统共性于其他系统中。但在我们的工作中,我们将共性视为可在不同系统中使用的模式。
4 一种基于层次的自适应系统建模方法
在本节中,我们提出了一种以模块化方式设计自适应系统的方法。该方法定义了两个主要阶段:在领域工程阶段进行为重用而开发,在应用工程阶段进行利用重用的开发(图2)。
第一阶段允许在特定领域内开发系统架构,能够明确表示系统的共性与可变特性。该阶段的成果将在Application Engineering中被使用。第二阶段则在特定领域内构建满足用户需求的具体系统。
4.1 领域工程
在我们的工作中,领域工程阶段的目的是为自适应系统的设计开发一种架构。
特征建模 :本阶段的起点是定义用于设计系统的特征模型。该特征模型(或称特征图)(Czarnecki和Eisenecker,2000;Czarnecki等,2005;Greenfield等,2004)是一种表达可变性的常用方法,可用于构建架构模型(C1)。它由特性层次结构组成,父特性与其子特性之间的关系被分为:
- 必选(共性):子特性是必需的。
- 可选(可变性):子特性是可选的。
- 或:必须选择至少一个子特性。
- 异或:必须选择其中一个子特性。
每个特性都可以通过一个或多个资产实现。为了构建软件产品,会组合不同特性的资产。
领域设计 :在我们的工作中,我们将设计模式视为构建自适应系统的资产。特征层次结构由三个抽象层表示:功能层、逻辑层和技术层。功能层使用通用架构中的监控‐分析‐规划‐执行‐知识架构(MAPE‐K架构)(IBM,2006)作为必需特征。MAPE‐K是由IBM定义的一种模型,用于规范FCL的不同活动。MAPE‐K的各个组件:Monitor、Analyse、Plan和Execute分别用于定义FCL的活动:Collect、Analyse、Decide和Act。MAPE‐K组件的主要功能定义如下。Analyse从上一活动(监控)收集数据,并识别出需要系统采取特定动作的症状。Plan从活动中收集信息,并决策被监控系统应如何进行适应以实现目标和目的。Execute基于规划活动推荐的动作,利用执行器改变被监控系统的行为。此外,Knowledge资源表示由MAPE‐K范式的四个活动共享的信息库。该架构帮助设计者定义自适应系统组件,并在下一层中选择合适的模式。其次,逻辑层为系统的整体结构提供骨架。它通过使用为开发自适应系统而定义的设计模式(本文称为逻辑模式)来细化系统组件(Ramirez 和 Cheng,2009)。最后,技术层解释了适应过程如何在更低的抽象层次上进行设计。它使用 GoF(四人组)设计模式(此处称为技术模式)(Gamma 等人,1995)来定义与系统运行相关的各个方面。
模式域 :是领域设计中所选模式的共性、可变类以及可变类之间依赖关系的显式表示。我们将模式的类视为构建系统各个组件的资产。模式的共性类被定义为必选特征,而可变类则被定义为可选特征。特征之间的相互依赖关系源自模式类图中定义的类间依赖关系。模式域用于生成可重用软件组件(图3)。
特征模型中的传感器工厂模式(根特征)将抽象传感器定义为必选特征,而将注册表和资源管理器定义为可选特征。抽象传感器特征提供两种类型的传感器:简单传感器、复杂传感器或两者都包含。此外,选择注册表特征意味着必须同时选择资源管理器特征。图3中特征模型所呈现的当前传感器工厂模式设计是六种有效组合之一。在此组合中,我们选择了该模式的所有组件。
4.2 应用工程
应用工程阶段根据用户提出的需求,从领域工程中选择需求(特性)来构建特定系统。
在此阶段,功能层定义了MAPE‐K架构中每个组件的主要功能和属性。随后,逻辑层通过使用逻辑模式来细化系统组件。这些模式对正在开发的系统施加的初始约束较少,同时提供了一个需要在技术层进一步丰富的一般模型。借助这些设计模式,开发者仅选择其应用所需的适应机制。在该层中,我们的目录包含以下模式:传感器工厂、适应性检测器、基于案例的推理 和 系统重构 模式(Ramirez 和 Cheng,2009),分别用于定义系统组件:监控、分析、计划 和 执行(表1)。
表1 为逻辑层选定的逻辑模式目录
| 组件 | 逻辑模式 |
|---|---|
| 监控 | 传感器工厂: 可在每个被观察组件分布且提供可探测所需信息的接口时使用。 |
| 分析 | 适应性检测器: 解释监控数据并确定何时需要进行适应。 |
| Plan | 基于案例的推理:在能够可靠识别需要重构的场景时,用于选择重构计划。能够可靠地识别需要重构的场景。 |
| 执行 | 系统重构:可用于重新配置采用客户机‐服务器架构结构的系统。客户机‐服务器架构。 |
技术层解释了适应过程在较低抽象层级中的设计方式。在该层中,我们对从逻辑层获得的设计进行细化。对于每个逻辑模式,我们尝试找到一个或多个技术模式。这些技术模式可以指定整个逻辑模式或其部分的结构和行为(C3)。这些抽象层按分层顺序排列,从最通用的(功能层)到最具体的(技术层)。在从较高层级向更具体层级的转换过程中,自适应系统的设计被逐步细化(C2)。监控组件将在下一节中进一步细化。
5 建模单个组件
在本节中,我们介绍了不同层中的Monitor组件(图4)。在自适应系统中(位于功能层),Monitor组件的主要功能是收集来自受管资源及其上下文的信息,以反映被监控系统的变化。Sensor Factory模式(Ramirez 和 Cheng,2009)(位于逻辑层)可用于每个被观测组件分布且提供可探测接口以获取所需信息的情况。在此逻辑模式中,可使用Simple Sensor对象来感知受管资源中需要被监控的组件。此外,该模式使用三个主要对象:Sensor Factory, Resource Manager和Registry。
- 第一个对象负责管理受管资源中传感器的添加和移除,客户端通过与此对象交互来访问传感器
- 第二个对象确定现有传感器是否可以与一个或多个客户端共享,同时还确定受管资源是否有足够的资源来部署新传感器
- 最后一个对象负责跟踪受管资源中已部署的传感器。
技术层中的传感器工厂(在该技术层中)定义了三个主要功能(或属性):传感器、传感器组合以及对不同传感器的管理。这些主要功能可通过三种技术模式来识别:观察者、组合和命令(表2)。
表2 监控组件中发现的技术模式目录
| 监控组件的技术模式 |
|---|
| 观察者 :对象之间的一对多关系,使得当一个对象改变状态时,所有其依赖项将自动收到通知并更新。 |
| Composite : 将对象组合成树形结构以表示部分‐整体的层次结构。 |
| Command : 使特定动作的请求者与执行该动作的对象解耦,执行该动作。 |
在 Client 对象和 Simple Sensor 对象之间可以使用 Observer 模式。Client 对象扮演观察者的角色,Simple Sensor 对象扮演主题的角色。该模式的主要目标是使系统能够监控可能导致重新配置的受管资源和环境条件。观察者角色收集有关监控系统及其环境的信息。主题角色用于表示系统中任何需要执行监控的组件。
Composite 模式可用于三个对象之间:Abstract Sensor 对象、Complex Sensor 对象和 Simple Sensor 对象。这三个对象分别扮演组件、组合和叶的角色。组件角色共享一个接口,用于常见的操作,如推拉数据。组合角色允许从各个叶子报告复杂数据类型,并执行板载计算。叶子角色表示基本传感器,能够报告布尔型、整数型和实数类型的数据。
命令模式用于指定在监控系统中添加新传感器的行为。它使用了四个对象:客户端对象扮演客户端角色,传感器工厂对象扮演调用者角色,资源管理器对象和注册表对象分别扮演具体命令角色。在此模式中,调用者角色负责管理在资源管理器和注册表对象中传感器的添加与移除。客户端通过与这些对象交互以获得对传感器的访问权限。第一个具体命令角色(由资源管理器对象定义)确定现有传感器是否可以被一个或多个客户端共享,并确定受管资源是否有足够的资源来部署新传感器。第二个具体命令角色(由注册表对象定义)负责跟踪在受管资源上已部署的传感器。
6 反馈循环的模块化
在本节中,我们介绍整个架构的设计以及其余组件:Analyse、Plan 和 Execute,并细化各组件之间的关系。
6.1 模块化MAPE-K组件
在本节中,我们将介绍逻辑层和技术层中的其余组件。
在逻辑层(图5)中,分析 模块解释来自传感器的数据。为此,我们使用适应性检测器模式。该逻辑模式将来自传感器工厂模式的更新值与特定的阈值进行比较。每个阈值包含一个或多个边界值。这些值用于表示正常行为与异常行为之间的界限。一旦阈值分析器指出可能需要进行适应的情况,适应性检测器就会向计划模块创建一个触发器。该模块使用一种基于案例的推理模式来选择特定的重构,并展示如何在运行时执行这些重构。
当可以可靠地识别需要重新配置的运行时场景时,应用基于案例的推理逻辑模式。该模式的重要对象包括触发器、推理引擎、决策和固定规则。
- 触发器 对象包含有关引发适应请求的原因的相关信息。它至少应提供关于错误源和观察到的错误类型的详细信息。
- 推理引擎 对象负责应用一组规则,以决策的形式产生一个动作。
- 决策 对象表示一个重构计划,该计划将使系统产生期望的行为。
- 固定规则 对象包含一组规则,用于指导 推理引擎 生成 决策。
执行 组件使用 系统重构 逻辑模式(Ramirez 和 Cheng,2009)。该模式可用于展示如何安全地重新配置组件。此模式的重要对象包括 适应驱动器、变更管理器、 驱动器、重构计划、重新配置规则、请求缓冲区、状态 和 组件。
- 适应驱动器 对象负责确保由 推理引擎(参见 基于案例的推理 模式)选择的 决策 被排队以进行后续处理。
- 变更管理器 对象提供对组件及其互连的加载和卸载的支持。
- 驱动器对象通过状态接口管理参与重构的组件的操作状态。
- 重构计划对象存储了在运行时重新配置系统的具体指令序列。
- 重新配置规则 对象包含用于指定系统中基本重新配置操作执行方式的规则和指令。其中一些操作包括组件插入、移除和交换。
- 请求缓冲区 对象是一种用于在重构期间存储决策的数据结构。
- 状态 对象定义了组件的状态。
- 组件 对象表示任何可在系统中部署的可执行组件。
系统重构模式的行为在图6中通过转换图展示。每个状态代表系统的结构变体。该结构变体由一组组件构成。此外,这些组件与一组重新配置规则相关联。结构变体之间的转换表示重构计划。可变性通过由组件定义的不同配置来体现。
在技术层(图7)中,适应性检测器逻辑模式使用装饰器技术模式向系统组件动态地添加附加职责。装饰器模式可用于将传感器工厂模式获取的更新值与特定的阈值进行动态比较。此外,通过使用阈值分析器,它还能指示可能需要进行适应的情况。这些情况可由装饰器角色指定。
策略 技术模式通过定义一个算法族来细化 基于案例的推理 逻辑模式。这些算法替换了 固定规则对象,并利用一个知识库(规则),将特定的监控场景(触发器)与一系列重构指令(决策)相关联。应用此模式可将功能逻辑与适应逻辑分离,从而针对不同事件对重构响应集进行聚类。
在逻辑层中,我们使用了系统重构模式来实现执行组件。在技术层中,我们使用三种技术模式桥接器、状态和迭代器来细化该实现。
- 桥接器模式可用于重构计划对象和重新配置规则对象。重构计划充当抽象的角色,而重新配置规则则充当实现者的角色。通过应用此模式,我们可以独立地扩展抽象和实现者层次结构。
- 状态 模式可以在三个对象之间使用:驱动器、状态 和 组件。这三个对象分别扮演上下文、状态和具体状态的角色。上下文角色通过状态接口管理组件的状态。状态角色定义了一个用于封装与特定状态相关行为的接口,它要求组件定义哪些状态对应于激活、被动和静止状态。具体状态角色实现了与上下文状态相关联的行为,它表示任何可在整个系统中部署的可执行组件。该模式允许系统的每个组件在其内部状态发生变化时改变其行为。
- 迭代器 模式可用于 适应驱动器 对象和 请求缓冲区。其中,适应驱动器 对象充当聚合角色,而 请求缓冲区 充当迭代器角色。通过应用此模式,我们可以访问用于存储决策的数据结构,而无需暴露其内部结构。
6.2 模块化组件间的关系
为了构建完整的自适应架构,将不同的模式进行组合(或组合化)。在本小节中,我们介绍了在不同抽象层中模式的组合方式。组件之间的关系由知识组件确定。该组件(位于功能层)表示由MAPE‐K范式活动共享的信息库。
表3 逻辑模式之间的关系
| 第一个组件(模式)/调用者 | 第二个组件(模式)/被调用者 |
|---|---|
| 客户端(传感器工厂) | 观察者(自适应检测器) |
| 触发器(自适应检测器) | 触发池(基于案例的推理) |
| 决策(基于案例的推理) | 重构计划(系统重构) |
知识 组件(位于 逻辑层)指定了逻辑模式的组成。传感器工厂 模式使用传感器来截取被观察系统的上下文。适应性检测器 模式通过其 客户端 接口观察传感器数据。当该模式发现需要进行过程适应的情况时,会向 基于案例的推理 模式创建包含适当信息的 触发器。该模式查找与这些 触发器 相关联的适当决策,并将其传递给 系统重构 模式。该模式可用于重新配置系统中的组件。为了识别逻辑模式之间的关系,我们采用 基于调用的组合 方法(Cacho 等人,2006)。在此方法中,两个或多个模式是分离的,且没有共同的类,这些模式的角色仅通过一个或多个方法调用进行连接。表3 概述了不同逻辑模式之间的各种关系。
表4 技术模式之间的关系
| 模式用于 | 自适应 系统 | 类 | 技术模式 | 角色 |
|---|---|---|---|---|
| 观察者 | 主题 | 简单传感器 | 组合 | Leaf |
| 观察者 | 观察者 | 命令 | 客户端 | 客户端 |
| 责任链 | 处理器 | 抽象传感器 | 组合 | 组件 |
| 复杂传感器 | 组合 | 组合 | 传感器工厂 | 命令 |
| 调用者 | 注册表 | 命令 | 命令 | |
| 传感器工厂 | 资源管理器 | 命令 | 命令 | |
| 重构计划 | 桥接器 | 抽象 | 责任链 | 处理器 |
| 重新配置规则 | 桥接器 | 实现者 | 驱动器 | 状态 |
| 上下文 | 状态 | 状态 | 状态 | 组件 |
| 状态 | 具体状态 | 适应驱动器 | 迭代器 | 聚合 |
| 重构 系统 | 请求缓冲区 | 迭代器 | 迭代器 |
为了识别技术模式之间的关系,我们采用了 Class-level interlacing 方法(Cacho 等人,2006)。在此方法中,两个或多个模式存在一个或多个共享类。这些模式的角色通过这些共享类中不同的方法和属性集来实现。表4展示了技术模式之间存在的一些关系的概览。
7 案例研究‘智能家居’
在本节中,通过一个案例研究来证明我们方法的可行性。我们选择了一个智能家居场景。该智能家居被视为家庭自动化的一个产品线。我们根据第4节中提出的方法对智能家居进行分析。我们的目标是提高智能家居系统中涉及的软件组件的模块化和可重用性。在此情况下,我们尝试研究安全系统的场景。
7.1 领域工程阶段
该阶段通过使用MAPE‐K架构(表5)来定义安全场景的不同组件和所选模式。在此阶段,从特征模型(在第4节中定义)中选择不同的模式。
表5 安全场景的不同组件和模式
| MAPE-K 组件 | 智能家居组件或 函数 | 逻辑模式 | 技术模式 |
|---|---|---|---|
| 监控 | 门、窗户、玻璃破碎 和运动探测器 | 传感器工厂 | 观察者和 组合 |
| 分析 | 断路传感器、门传感器和 运动探测器 | 适应性检测器 | 装饰器 |
| Plan | 触发警报,和/或 打开灯 | 基于案例的 推理 | 策略 |
| 执行 | 激活警报器和/或 bell | 重构系统 | 桥接与状态 |
在监控组件中,我们使用以下传感器:门、窗户、玻璃破碎和运动探测器。在分析 组件中,可以指定需要系统采取特定动作的症状。例如,必须使用玻璃破碎传感器、门传感器和运动探测器来检测是否有未经授权的人员试图进入房屋。在计划组件中,我们规定检测到入侵后需要采取的主要决策,例如触发警报和/或打开房屋中的灯光。在执行组件中,我们规定由规划活动推荐的动作。例如,在警报决策中,我们可以定义两种类型的执行器:警报器和铃铛。图8展示了不同MAPE‐K组件中安全场景的特征图。
7.2 应用工程阶段
该阶段通过使用逻辑模式、技术模式以及利用EcaesarJ语言(Nunez 和 Gasiunas,2009)实现部分技术模式来细化系统。下文将进一步解释选择这些模式对安全场景进行建模的原因。
7.2.1 应用设计
通常,智能家居中使用的不同传感器是外部可用的分布式组件。每个传感器都提供一个接口,可用于识别环境的上下文情况。在逻辑层的Monitor组件中,我们使用了 Sensor Factory逻辑模式;该模式可在组件(传感器)是分布式的,每个组件(传感器)提供一个接口,可用于探测所需信息。在此逻辑模式中,我们可以识别出两个部分:传感器(观察者 技术模式)和传感器的组合(组合 技术模式)。在安全场景中使用的不同传感器具有可组合的能力。它们收集上下文信息,并能够相互通信以获取所需信息。
我们使用适应性检测器逻辑模式来指定分析组件。该模式对于解释监控数据并识别观察到的行为偏离预期行为的情况至关重要。在智能家居中,该模式用于识别观察到的行为偏离预期行为的情形,例如门或窗户被打开、玻璃破碎探测器检测到玻璃破碎的声音,以及入侵者进入由运动探测器保护的房间。
通过在基于案例的推理逻辑模式的计划组件中使用,我们可以指定以下规则:内部防护(入侵级别1)和周界防护(入侵级别2)。这些防护(固定规则)被视为已定义的规则。在周界防护(规则)中,我们使用门、窗户和玻璃破碎传感器。如果一扇门或一扇窗户被打开和/或玻璃破碎探测器检测到玻璃破碎的声音(触发器),则触发警报(决策)。在内部防护(规则)中,我们仅使用运动探测器传感器。如果该传感器检测到入侵者进入房间,警报将转为通知警示;如果该传感器检测到另一名入侵者移动,则激活警报。服务启用与管理平台组件(推理引擎)用于扫描规则并找到适当响应触发器的决策。图9展示了基于案例的推理模式的特征模型。
在 执行 组件中,我们仅使用 系统重构 逻辑模式。该模式可用于展示如何在运行时安全地重新配置执行器。由于执行器是手动插入和移除的,因此在智能家居系统中无法使用 组件插入 和 组件移除 模式。图10 表示了 系统重构 模式的行為。我们识别出三种系统的结构变体,分别对应四种可能的状态:关闭、布防、注意和警报。在这些结构变体中,我们展示了两个 组件:门(代表一个传感器组件)和警报器(代表一个执行器组件)。门组件
与之关联有两个可能的重新配置规则,即启用和解除。警报器组件关联有三个可能的重新配置规则,分别对应开启、通知警示和关闭。结构变体之间的转换表示来自适应场景的重构计划所产生的事件。例如,从已启用变体到报警变体的适应发生在入侵事件等级1或入侵级别2时(图10)。
7.2.2 应用开发
在技术层中,我们介绍了四种技术模式的实现:观察者模式、组合模式、策略 模式 和状态模式。选择EcaesarJ作为实现智能家居模式的语言(Nunez 和 Gasiunas,2009)。该语言是一种面向切面语言,对可重用性提供了强有力的支持。它是 Java的扩展,并集成了其前身语言CaesarJ的特性。EcaesarJ中的关注点分离通过协作接口来实现。在这些接口中,可以将可重用部分与应用程序特定部分分开。这是通过将协作接口分为提供部分和期望部分来实现的。提供部分使用可重用的 EcaesarJ组件实现,它实现了系统的共性。期望部分使用EcaesarJ绑定实现,它实现了系统的变异性。不同特性的实现可以通过抽象族类相互解耦。此外, CaesarJ的切入点已被更通用的事件概念所取代。同时,提供事件的特性与定义事件处理的组件也实现了相互解耦。
7.2.2.1 观察者模式的实现
EcaesarJ语言定义的‘事件’概念用于指定观察者模式的结构。一个事件具有源 (或主题)以及对该事件感兴趣的多个目标(或观察者)(Rashid 等,2011)。事件有两种类型:显式事件和隐式事件。显式事件由源显式触发,并作为通知发送给需要对源变化做出响应的目标。隐式事件则考虑程序状态的所有可识别变化。在安全场景中,我们定义了一个显式事件 activityDetected。当报警系统处于布防状态时,房屋内的任何活动都可能被视为入侵行为,例如:门已打开、窗已打开、玻璃破碎和/或运动探测器被触发(清单1)。
清单1 使用EcaesarJ在智能家居中实现观察者模式
1 abstract cclass IActivityDetection {
2抽象事件 activityDetected();}
3 cclass AlarmControl 需要 IActivityDetection {
4事件 intrusion() = activityDetected() && if(isArmed());
5入侵 () =>{
6 fireAlarm ();}
7 }
7.2.2.2. “组合”模式的实现
在智能家居中,不同的传感器分布在整栋房屋内。要访问特定的传感器,我们必须浏览房屋结构。使用模式 Composite 来定义房屋的组合结构,例如:位置、组合位置、房间、楼层和房屋(清单2)。
Listing 2 智能家居中使用EcaesarJ的组合模式
1 cclass 房间 extends 位置 {}
2 cclass楼层 extends 组合位置 {
3 List<房间>房间;
4 List<房间>房间() { return 房间; }
5 void addRoom(Room r) { 房间.add(r); }
6 List<? extends 位置> locations() { return 房间(); }
7 }
8 cclass 房屋 extends 组合位置 {
9 List<楼层>楼层;
10 List<楼层> floors() { return floors; }
11 void addFloor(Floor r) { floors .add(r); }
12 List<? extends 位置> locations() { return floors(); }
13 }
7.2.2.3 策略模式的实现
抽象事件能够使事件的定义独立于对事件的反应(策略)而变化(Nunez 和 Gasiunas,2009)。根据一组可选特性中的选择,事件可以有不同的定义方式。在我们的场景中,报警系统需要在房屋发生入侵时触发警报。activityDetected 事件 在清单 3 的第 2 行声明,可根据多种独立的房屋传感器(如:运动传感器、门传感器、碎玻璃传感器等)的不同组合来实现。
清单 3 使用EcaesarJ在智能家居中实现策略模式
1 cclass DefaultActivityDetection extends IActivityDetection {
2事件 activityDetected() =空;}
3 cclass 运动活动检测 extends DefaultActivityDetection
4需要 IHouseMotionSensors {
5混入 事件 activityDetected() = super.activityDetected() ||
6存在(house().motionSensors()).motionDetected();
7 }
8 cclass 门活动检测 extends DefaultActivityDetection
9需要 IHouseDoorSensor {
10混入 事件 activityDetected() = super.activityDetected() ||
11存在(house().door()).open() }
.
.
12 cclass 我家的活动检测 13 extends 运动活动检测 & 门活动检测 &
Brokenglass活动检测 {}
7.2.2.4 “状态”模式的实现
状态 模式可以改变执行器和系统的状态。在本节中,我们讨论系统的状态。EcaesarJ 使用状态机构造来根据对象的逻辑状态组织事件(Nunez 和 Gasiunas,2009)。状态机可以表示为形式 (S1, E => A, ->S2)。在状态 S1 中,事件 E 引发动作 A 的执行,并使状态机转换到状态 S2。事件处理器可以在使状态机转换到下一状态之前返回一个值或抛出异常,该状态转换用操作符 -> 标记(Nunez 和 Gasiunas,2009)。
在清单4中,我们尝试给出一个包含两个状态的示例:布防和警报。这些状态使用关键字state作为类成员引入。状态布防包含一个关键字initial,用于声明其对应于状态机的初始状态。状态布防定义了两个分支,一个用于事件setAlarm,另一个用于事件intrusion。这些分支通过选择操作符 |进行分隔。
Listing 4 在智能家居中使用EcaesarJ实现状态模式
1 abstract cclass IActivityDetection {
2 cclass AlarmControl
3 protected abstract void 设备设置警报(布尔型 警报); 4抽象事件 intrusion(); 5 }
6 }
7...
8 cclass BaseAlarmControl 需要 IActivityDetection { 9 cclass AlarmControl { 10 事件 void setAlarm(布尔型 alarm); 11 事件 void intrusion (); 12
13 状态 初始 Armed =14 (setAlarm(布尔型 alarm) =>15
deviceSetAlarm(alarm); -> Armed16 \| intrusion() => ->Alarm 17 ); 18
19 状态 Alarm =20 (setAlarm (int alarm) =>21 throw new
CommandFailedException() -> Armed22 \| intrusion() => ->Alarm 23 ); 24 } 25 }
8 评估和讨论
在本节中,我们评估并比较了智能家居案例研究(通过EcaesarJ实现)中使用的设计模式与相关工作部分中介绍的面向对象模式(通过Java实现)。此外,我们分析了在安全场景下智能家居的可扩展性和灵活性。为了能够分析我们的方法,我们采用了阿萨多利等人(2009年)提出的一些定性和定量属性。
8.1 评估
为了分析这项工作,我们使用了一些软件属性:可重用性、可扩展性、可扩展性、可用性和灵活性。这些属性已被其他研究者用于评估自适应系统工程方法,例如阿萨多利等人(2009年)和克里卡瓦等人(2014年)。
可重用性 。 此属性指的是现有应用程序可在多大程度上被重用于新应用程序中。在该属性中,我们基于软件工程中的一些量化标准:关注点分离、耦合和内聚,对逻辑层和技术层中使用的不同模式的 Java 与 EcaesarJ 实现进行比较。
为了分析关注点分离,我们使用两个属性:组件间关注点扩散(CDC)和操作间关注点扩散(CDO)(Cacho 等人,2006)。此外,我们还使用两个属性:模块间耦合(CBM)用于计算耦合度,以及缺乏内聚(LCO)用于计算内聚度。CDC 统计主要目的是实现某个关注点的模块数量,以及访问这些模块的其他类和协作接口的数量。CDO 统计主要目的是实现某个关注点的操作数量,以及访问这些操作的其他方法和通知(advices)的数量。CBM 统计一个模块所耦合的模块数量。LCO 统计模块中不访问相同实例变量的操作数量(Cacho 等人,2006)。
在图11中,我们评估了两种逻辑模式的组合:来自监控组件的传感器工厂模式 与来自分析组件的适应性检测器模式,以及来自计划组件的基于案例的推理 模式 与来自执行组件的系统重构模式。使用EcaesarJ实现逻辑模式在组件间扩散数量 (CDC)方面表现出更好的结果。EcaesarJ解决方案将负责模式关注点的方法从类转移到协作接口和EcaesarJ实现中。因此,操作的数量并未减少(CDO),但组件间的扩散(CDC)减少了。逻辑模式之间的调用可以通过EcaesarJ的提供部分来实现。在这种情况下,逻辑模式的(CBM) tends to be worse。
在图12中,我们评估了两种技术模式的组合。第一种组合由监控组件中的观察者模式和组合模式定义。这两种模式共享简单传感器类。第二种组合由执行组件中的桥接器模式和知识组件中的责任链模式定义。这两种模式共享重构计划类。
在技术层中,所有EcaesarJ解决方案通常在通过技术模式实现关注点分离[( CDC)和(CDO)],以及内聚(LCO)方面均表现出显著优势。而Java解决方案在共享类之间的关注点分离较差且内聚性较低。此外,其操作之间的耦合也较弱。
可扩展性 。 该属性表明系统在适当处理不断增长的负载量方面的能力。为了评估系统的可扩展性,我们对 Java 和 EcaesarJ 的两种实现中的某些功能进行了更改,并统计代码中发生关注点切换的位置数量。如果更改后位置数量增加,则认为系统不可扩展;如果保持不变,则系统具有可扩展性(Garcia 等,2006)。如表6所示,在9种技术模式中有4种(44%)的实现确认了 EcaesarJ 中的可扩展性。此外,没有任何 Java 实现确认具备可扩展性。
表6 使用技术模式的可扩展性
| 技术模式 | J ava (面向对象) | EcaesarJ (面向方面) |
|---|---|---|
| 观察者 | No | Yes |
| 组合 | No | No |
| 命令 | No | Yes |
| 装饰器 | No | Yes |
| 策略 | No | No |
| 状态 | No | No |
| 桥接器 | No | No |
| 迭代器 | No | No |
| 责任链 | No | Yes |
可扩展性 。 此属性允许开发者扩展该方法以添加新特性或将其与其他方法集成。在此属性中,我们分析在不同阶段或不同情况下可以获得的设计或配置变体的数量模式(表7)。通过图1分析阶段中定义的特征模型,我们可以创建314,250个不同的有效实例。本文中呈现的示例是智能家居中存在的314,250个有效组合之一。此外,所提出的设计是逻辑模式生成的112个有效设计之一。在我们的案例中,我们选择了以下逻辑模式:Sensor Factory、Adaptation Detector、Case-Based Reasoning 和System Reconfiguration模式。通过这些逻辑模式,我们可以获得96个有效的技术设计。
表7 不同阶段的可扩展性
| 分析 阶段 | 设计阶段 (逻辑层) | 传感器 工厂 模式 | 适检应测性器 模式 | 基于案例的 推理 模式 | 重离新系子配统模置式 设阶计段 (技层术) |
|---|---|---|---|---|---|
| 314,250 有效 配置 s | 112 有效 设计 | 6 有效 设计 | 2 有效 设计 | 2 有效 设计 | 4 有效 设计 |
| 96 有效 设计由 one logical 设计 |
可用性 。 该属性决定了在应用中使用该方法的难易程度。EcaesarJ 提供了许多概念,如事件概念和状态机结构,以促进技术模式关注点的实现。表8 展示了存在的一些技术模式与 EcaesarJ 概念之间的关系。
表8 使用EcaesarJ概念的技术模式
| Technical patterns | EcaesarJ定义的概念或机制 |
|---|---|
| 观察者 | 事件概念 |
| 组合 | 协作界面和房屋结构 |
| 策略 | 抽象事件 |
| 状态 | 状态机结构 |
灵活性 。 此属性允许开发者在其自我管理逻辑的设计和实现中结合自身方法。在此属性中,我们根据 [19] 中定义的标准:自主程度、控制范围、自*属性和管理逻辑,分析智能家居在安全场景下的灵活性。自主程度表示一种方法在自动化管理过程方面的能力,其范围从手动到完全自主。控制范围表示被管理对象的粒度。自*属性支持该方法应对自配置、自愈、自优化和自我保护属性的能力。管理逻辑表达了定义自管理需求的机制(例如,描述性或编程式)。
表9展示了智能家居系统在安全场景下的灵活性概述。在自主程度的闭环级别上,智能家居系统能够根据环境中的可用信息和相关知识自动执行动作。在控制范围属性的同一类型多实例级别上,同质资源被管理,通常以集合形式存在,例如收集物理信息的传感器(如灯光、恒温器等)以及执行器(如打开窗户、启用警报等)。主要的自适应属性
表9 智能家居中的灵活性
| 标准 | 带有安全场景的智能家居 |
|---|---|
| 自主程度 | 闭环 |
| 控制范围 | 多个实例 |
| 自*属性 | 自我保护 |
| 管理逻辑 | 编程式使用 EcaesarJ |
8.2 讨论
根据上一小节中展示的结果,所提出的方法凸显了存在的一些优势。
我们的方法通过定义一个技术层而展现出优势。该层确保与技术模式的完美内聚。基于模式的方法(Gomaa,2011;Ramirez,2008;Chowdhury 和 Katchabaw, 2012a;Mannava 和 Ramesh,2012)仅提供了一个抽象层次,在本研究中称为逻辑层。事实上,逻辑模式未能提供有效的解决方案来降低组件之间的耦合并提高内聚。我们工作的主要优势在于支持设计中的可变性。通过我们的方法,在建模的第一步即可获得110多种有效设计。在逻辑层选择表1中的模式后,可在技术层获得90多种有效设计。
在 Ramirez(2008)的方法中,我们只能得到 112 种有效设计。Chowdhury 和 Katchabaw( 2012,2013,2012b)的方法以及 Mannava 和 Ramesh(2012)的研究仅提供了一种有效设计。EcaesarJ(面向切面)语言还为我们的方法提供了优势,因为它提供了一些比 Java实现更便于模式实现的概念。
9 结论与未来工作
在本文中,我们提出了一种以模块化方式设计自适应系统的方法。我们的方法是首个能够将可变性与可重用性相结合应用于自适应系统的方案。基于特征建模和设计模式,该方法在两个阶段支持系统的可变性和可重用性。第一阶段通过应用可变性管理来生成可重用的自适应软件;第二阶段则利用设计模式的专业知识构建特定系统,以满足用户需求。
我们的方法面临着第2节中指出的挑战。针对第一个关于结构可变性的挑战, 我们采用了特征建模方法。这种建模是表达可变性的一种众所周知的方法。对于第二个挑战,即显式地建模FCL,我们采用了一种基于三层的方法:功能层、逻辑层和技术层。在从较高层次向更具体层次的转换过程中,系统的设计得到细化。对于最后一个挑战,即确保组件的模块化和可重用性,我们在不同层次的抽象中使用了设计模式。这些模式将适应逻辑与功能逻辑分离。这种关注点分离有助于在多个自适应系统中重用适应设计。
关于未来工作,我们正在考虑自适应系统的动态变异性。这种动态推导允许定义一种方法,以在系统执行期间根据产品所支持的特性来维护和更新产品状态。我们还将尝试通过使用布尔表达式中的满足性重新定义约束分析,从而以形式化方式对特性进行规范。这种形式化规范将为在不同应用场景中重用特性打开大门。
自适应系统建模与设计模式结合

562

被折叠的 条评论
为什么被折叠?



