使用 UML 进行业务建模:理解业务用例与系统用例的相似和不同之处
 
作者:Arthur V. English 出处:IBM
 
本文内容包括:

本文来自于 Rational Edge:学习有关业务用例与系统用例相似和不同之处的知识,包括应该使用什么样的 UML 图,通过 IBM Rational Software Architect 或者其它建模工具来建模这些用例。

绝大多数构架师都认为业务建模是开发软件解决方案中到一个非常重要的活动。成功的解决方案会支持这个业务,它们能够解决业务问题并确保业务目标的实现。

当开发一个合理的业务模型以后,业务流程分析员能够探究不同业务改进的选项,比如取消多余的任务,使重复且平凡的任务或者容易出现的错误实现自动化操作。 IBM® Rational Unified Process®,或者 RUP®,以及 Unisys 3D Visual Enterprise, 或者 3D-VE, 或者 3D-VE,提供了一个系统化的方法,利用统一建模语言(UML)可以直观地表现业务模型,同时还可以派生出一个一致的且能够追溯到这个业务模型的起点系统用例模型。

这篇文章提供了 RUP 业务建模的概述,并解决了以下的问题:

  • 业务用例模型与系统用例模型有怎样的相似之处?
  • 业务用例模型与系统用例模型有什么不同之处?
  • 构建业务模型应该使用哪个 UML 图?
  • 业务用例模型与系统用例模型之间有什么关系?

背景

在谈论这个问题之前,我想解释一下为什么要挑选这个特殊的话题来写。自从1990年我就作为一名软件构架师从事系统用例的工作。当我是一名由 Unisys Global Public Sector 开发的 Integrated Justice Information Sharing (IJIS) 框架解决方案的总构架师时,还没有接触到业务用例,直到2002年。IJIS 现在已经发展成为 Unisys Information Sharing Management Framework (ISM)。

ISM 是一套支持信息共享的总体业务过程的可重用的组件。ISM Framework 利用 Service Oriented Architecture (SOA) 技术整合了不同类型的司法与公共安全系统,从而在关键决定点时分配关键的数据,文档以及图片。ISM 解决方案将为司法与公共安全 团体提供了一个业务框架、技术框架、基础应用软件以及方法,使政府机构能够继续使用他们的遗留系统。

ISM 是使用 RUP 进行设计的,ISM 业务模型是为 ISM 项目开发的首批工件之一。开发 ISM 业务模型对我来说是一个有意义的学习经历:我认识到的一个问题是,对于如何开发一个业务模型有很多含混不清的地方,为开发 UML 业务模型提供指导的文献相对比较少,而且有些不一致。

自从我离开 Unisys Global Public Sector 加入到 Unisys University 作为一名培训和开发顾问后,就一直负责开发和交付软件构架和 IBM Rational 工具培训。我的职责之一就是 IBM Rational 课程 "Mastering Requirements Management with Use Cases" (MRMUC) 的教学。这门课程主要阐述的是开发系统用例,但是这门课程仅仅提供了什么是业务模型以及它如何与这个系统用例模型相联系的一个很有限的讨论。因此这篇文章的目的之一就是为 MRMUC 课程补充材料。

这篇文章假定您已经有了系统用例建模和 RUP 需求规程的基本知识。如果您对系统用例建模并不熟悉,我建议您学习 RUP 需求规程的知识。

正如前面提到的,这篇文献关于业务建模的内容比较少,但是我们发现了一些非常有用的参考资料,远远多于您在 RUP 中找到的信息:

  • Writing Effective Use Cases, 由 Alistair Cockburn 编著。这是我最喜欢的关于业务和系统用例说明的著作。Alistair 强调一个业务或者系统用例模型最重要的部分是用例说明。这本书强调的就是用例说明,而不是 UML。
  • UML for the IT Business Analyst, 由 Howard Podeswa 编写。本书主要强调的是利用 UML 来开发一个业务模型,以及对 Alistair 的书进行补充。 UML for the IT Business Analyst 帮助我完成了关于如何开发一个有效的业务用例模型的课程培训。
  • Rational Edge 中的文章“Effective Business Modeling with UML: Describing Business Use Cases and Realizations”,由 Pan-Wei Ng 编写。那篇文章与这篇文章有些类似。那篇文章是从 UML 1.x 的角度来编写的。而这篇文章是从一个 UML 2.0 的角度来编写的,并且阐述了业务用例模型,业务分析模型,以及系统用例模型之间更深刻的关系。

既然我已经完成了预备工作,就让我们开始提一些问题。

业务用例模型与系统用例模型有什么相似之处?

业务用例模型与系统用例模型有很多相似之处。两个模型都有用例说明。如果您对业务用例模型以及系统用例模型的 RUP 模版进行检查,您会发现它们的格式十分相似。两者都包含先决条件、后置条件、扩展点 以及特殊需求。业务用例说明有基本的工作流和可选择的工作流,从而取代了基本的事件流和可选流。

业务用例说明与系统用例说明的格式十分相似,但是在设计范围上有些分歧。业务用例的设计范围是业务操作。它是这个组织外部的业务参与者,实现与业务组织相关的业务目标。让我们查看这个业务用例的 RUP 定义:

" 业务用例从一个外部的,增加值的角度来描述一个业务过程。为了给这个业务的涉众创造价值,业务用例是超越组织边界的业务过程,很可能包括合作伙伴和供应商。"

简单地说,这个定义标识了一些重要点,比如:

  • 一个业务用例描述的是业务过程——而不是软件系统过程。
  • 一个业务用例为涉众创造价值。这些涉众要么是业务参与者要么是业务工作者。
  • 一个业务用例可以超越组织的边界。有些构架师对于这一点有非常严密的态度。许多业务用例确实超越来组织的边界,但是有些业务用例仅仅关注于一个组织。我稍后将在这篇中给出一些例子。

让我们也看看 Podeswa 的书 UML for the IT Business Analyst 中对业务用例的定义:

"业务用例:业务过程是描述这个业务的具体工作流的;一次涉众与实现业务目标的业务之间的交互。它可能包含手工和自动化的过程,也可能发生在一个长期的时间段中。"

这个定义表明了通过实现业务目标创造价值的观点。它通过把一个业务过程描述成一个可能包含手工和自动化过程的具体工作流来详述 RUP 的定义。这个定义还指出,工作流可能发生在一个长期时间段中。所有的这些都十分的重要。

那么系统用例又是怎样的呢?系统用例的设计范围就是这个计算机系统设计的范围。它是一个系统参与者,与计算机系统一起实现一个目标。系统用例就是参与者如何与计算机技术相联系,而不是业务过程。

Cockburn 的 Writing Effective Use Cases 给业务和系统用例使用了相同的用例说明模版。业务用例与系统用例说明使用这个模版的区别是设计范围,而不是模版。Cockburn 想通过目标层次对用例进行分类,如表格1所示。

图1: Alistair Cockburn 对业务和系统用例的分类
高层概要
概要
用户目标
子功能
最低层

Cockburn 编写 Writing Effective Use Cases 的最初目标是系统用例,但他在业务用例上也花了很多精力。他利用目标层次来区分业务与系统用例,而不是使用不同的模版类型。那么这些图标和目标层次又意味着什么呢?

这些图标本身代表着一个简单的系统,它是根据用例与“海平面”(用户的实际层次)的相对高低来确定的。系统用例的最佳点是用户目标,通过海平面图标来表明。有时候需要将复杂的系统用例分解成其它有子功能目标、通过鱼图标表明的用例。但是您应该尽量避免将海平面系统用例分解成蛤或者最低层系统用例。

也许您会猜测到,概要或者蛤用例应该是业务用例。云或者高层概要也可能是业务用例。

Cockburn 的方法是将这些用例看作是一个光谱,从一个组织的最高层次业务目标,到为实现这些业务目标而执行的软件解决方案的需求详细资料。这种方法将系统用例看作是一个业务用例的分解。这个用例分解方法可以用来帮助您从这个业务模型驱动系统用例模型,我稍后会对这个问题进行讨论。

那么业务用例模型与系统用例模型图有什么其他相似之处呢?

  • 两者都有参与者。在业务用例图中,您将一个参与者原型化为 <<BusinessActor>>。
  • 两者都有用例。在业务用例模型中,您将一个用例原型化为 <<BusinessUseCase>>。
  • 在参与者与用例之间两者都有一个通信关联。
  • 业务用例和系统用例都能够包含、扩展,以及一般化关联。

用例图中的通信关联对于学习用例建模的人们来说,通常是一个容易混淆的地方。我应该使用箭头吗?这个箭头应该指向什么方向呢?通信关联已经被描绘出来,因为 1.4 UML 规范是一条实线。这条线可以配上一个箭头。这条线和箭头代表角色与系统之间的双方对话。如果呈现出一个箭头,那么说明只有这个关联末尾的“这个事物”能够发起通信。没有箭头的表明任何一方都可以发起通信(而不是两端都发起通信)。

UML 2.0 规范使它更简单。UML 2.0 不允许角色与用例之间或者业务角色与业务用例之间存在这种可灵活操作的关联。我个人比较喜欢箭头,但是如果您把 IBM Rational Software Architect (RSA) 当作您的 UML 建模工具,您就不能在角色和用例之间描绘出一个箭头。此时的 RSA 是完全没有错的。 UML 2.0 是通信关联不可灵活操作的原因。

既然我们已经讨论了业务用例模型和系统用例模型之间的相似之处,下面我们就看看它们的不同点。

业务用例模型与系统用例模型之间究竟有怎样的差别呢?

业务用例模型与系统用例模型之间主要有三点重大不同之处:设计范围、白盒测试与黑盒测试,以及业务操作者。

范围

在前面的部分中,我借助 Alistair Cockburn 的处于“水平线”上面、下面,或正好处于“水平线”的规定对设计范围进行了讨论。

业务用例着重于业务操作。它们表示实现业务目标的业务中的具体工作流。业务过程可能涉及手工和自动过程,并且在一段长期的时间内进行。

系统用例着重于要设计的软件系统。参与者如何与软件系统进行交互?我们在系统用例说明中书写的事件流应该足够详细,从而用作编写系统测试脚本的出发点。

白盒与黑盒

业务用例常常是以白盒形式编写的。它们描述了被建模的组织中的人和部门之间的交互。我们使用业务用例来说明在“现有”业务模型中组织如何工作。然后我们重构“现有”的业务用例模型,让其面向将要建模的组织的未来设计。我们需要创建什么新角色和部门来提供更多价值,或者消除业务问题?什么角色和部门需要消失?

系统用例几乎总是以黑盒形式编写的。它们描述了软件系统之外的参与者如何与将被设计的系统进行交互。系统用例详细阐明了系统需求。系统用例模型的目的是从涉众的角度说明需求,而不是设计如何满足需求。

业务角色

那么业务角色是什么?在系统用例图中,您只让参与者与用例进行交互。但在业务用例图中,您可以让业务参与者和业务角色与业务用例进行交互。

业务参与者是业务之外的人。它可以是一个角色或其他组织实体。例如,在刑事审判系统中,业务参与者可以是证人、嫌疑犯、外部的政府机构,例如健康服务,或业务实体,例如,业务资信咨询机构。

业务角色是业务内部的某个人或某个部门。在刑事审判系统中,业务角色可以是治安人员、法官、检察官,或假释官。当您实现了一个业务用例,并且创建了时序图和/或 通信图来显示业务参与者、业务角色,和业务实体如何协作执行业务用例时,您将会把业务角色从业务用例模型转入业务分析模型,并且加入所需的额外业务角色来提供业务用例功能。图 1 显示了基于 ISM 项目的示例业务用例图。

图 1:ISM 业务用例图

图 1 显示了一个业务参与者:嫌疑犯(Suspect)。有三个业务角色:执法人(Law Enforcement)、检察官(Prosecutor)和法院(Court)。有四个业务用例:逮捕被告(Arrest Subject)、请求担保(Request Warrant)、获得指纹和嫌疑犯照片(Capture Fingerprints and Mugshot),以及保释(Release on Bail)。获取指纹和嫌疑犯照片总是作为来自逮捕被告基础业务用例的强制行为。保释是继承逮捕被告业务用例的可选行为。

早先,我讨论了业务用例如何跨越组织边界,许多情况都是这样的。请求担保就是一个好例子。它涉及执法人和法院 。业务用例还可以只集中在一个组织上。获得指纹和嫌疑犯照片就是这样一个好例子。

我应该为业务建模使用哪些 UML 图?

在我讨论您在业务建模中使用的 UML 图之前,我想说一些关于使用 RSA 和 UML 2.0 创建业务用例图的提示:

  • 在 UML 1.x 中,您可以将参与者原型化为业务角色。在 UML 2.0 中,您必须创建一个类,然后将其原型化为业务角色。在 UML 2.0 中,您可以将参与者原型化为业务参与者,但您不能将参与者原型化为业务角色。
  • 在 UML 2.0 中,业务用例和业务角色之间的关联是可导航的。业务参与者和业务用例之间的关联是不可导航的。
  • 作为最佳实践,我推荐断开业务用例和业务角色之间的导航,从而保持业务角色与业务参与者的一致。业务角色及其用例关联应该按照业务参与者与业务用例通信的同样方式来绘制。
  • 您必须在您的工程的 Properties 标签页中选择 Profiles 选项卡,然后单击 Add Profile 按钮,来向您的工程中添加业务建模和健壮性分析原型。在 IBM Rational Rose 中,这是自动包含的。在 UML 2.0 中,概要文件用于包装原型和标记值 UML 扩展。UML 2.0 规范要求您向 UML 建模工程中添加概要文件来使用业务建模原型。

UML 业务模型包括两个模型:用例视图(Use-Case View)中的业务用例模型和逻辑视图(Logical View)中的业务分析模型。1业务用例模型中的主图是业务用例图。您还可以随意加入表示单个业务用例的 UML 活动图,来图形化地显示工作流过程,如图 2 所示,逮捕被告业务用例的活动图。

图 2:ISM 逮捕被告业务用例活动图

业务分析模型描述了通过业务角色和业务实体的交互来实现业务用例。它用作业务角色和业务实体需要如何相关联,以及它们需要如何协作,来执行业务用例的抽象。业务分析模型中有三种类型的 UML 图,如图 3 所示:类(Class)、时序(Sequence)和通信(Communication)图。

图 3:业务分析模型图

业务分析模型中的主要的图是时序图。您手工地创建显示出业务参与者、业务角色,和业务实体如何交互执行业务用例的时序图。时序图显示出以时间时序安排的对象交互。特别是,它显示出参与交互的对象,以及消息交换的顺序。

通信图是以前在 UML 1.x 中所称的协作图(Collaboration diagram),它描述了对象之间交互的模式,通过对象间的链接和发送给对方的消息来展示参与交互的对象。通信图和时序图都显示出交互,但它们强调了不同的方面。时序图清楚地显示出时间顺序,但没有明确地显示出对象关系。通信图清楚地显示出对象关系,但必须从顺序号那儿获得时间顺序。

两个图都显示出同样的行为,但方式不同。我个人喜欢时序图,因为它通常比较容易读懂。您还可以使用参与类的视图(View of Participating Classes,VOPC)来显示协作执行业务用例的业务参与者、业务角色和业务实体的静态视图。

图 4 显示出 ISM 逮捕被告业务用例实现的时序图。图 5 显示出 ISM 逮捕被告业务用例实现的 VOPC。图 6 显示出 ISM 逮捕被告业务用例实现的通信图。

图 4:ISM 逮捕被告业务用例实现的时序图

在 ISM 逮捕被告业务时序图这部分中,如图 4 所示,有三个从业务用例模型转入的业务角色:执法人、签署者(Subscriber)和刑事审判系统。刑事审判系统是执法人、法院、检察官,等等的一般化。为了让时序图简单化,我们使用该泛化来表示 ISM 可以使用的任意刑事审判系统。

图 4 还显示出引入到业务分析模型中的两个新的业务角色:档案管理系统(Records Management System,RMS)和 ISM Broker。RMS 通常是商业化成品(commercial off-the-shelf,COTS)解决方案,它将地方的执法用作刑事案件管理系统。ISM Broker 是 Unisys 计划开发的软件解决方案的自动化候选者或代理。

Unisys ISM 解决方案利用中心辐射型 SOA 技术整合了多个各种各样的司法系统,从而在重要决策点处,分享关键任务的数据、文档、图像和事务。ISM 可以在 Microsoft BizTalk Server 或 IBM WebSphere Business Integration 上实现。ISM Broker 作为在审判团之中数据共享的导管,并且利用当前的技术来推、拉、发布和订阅信息,从而支持日常的审判操作。

图 5:ISM 逮捕被告业务用例实现的 VOPC 图

图 5 中的 VOPC 图显示了参与逮捕被告业务用例的业务参与者、业务角色和业务实体的静态视图。注意为每个业务角色显示的操作。这些操作被称为业务职责。VOPC 图的更精确的名称是参与的业务参与者、业务角色和业务实体的视图(View of Participating Business Actors,、Business Workers 和 Business Entities)。在本实例中,只有业务角色协作执行业务用例。

图 6:ISM 逮捕被告业务用例实现的通信图

如前面所提到的,通信图(如图 6 所示)是观察时序图中所示行为的另一种方法。RSA 提供了从时序图创建通信图的自动能力,反之亦然。

还有一个要回答的问题。

业务用例模型和系统用例模型之间的关系是什么?

图 7,业务用例到系统用例的向下流动(Business to System Use-Case Flow Down),出自我所教授的 IBM Rational 课程“Mastering Requirements Management with Use Cases”。

图 7,业务用例到系统用例的向下流动

图 7 例举了课程中最难教授的主题之一,因为您要理解该图所需的大部分基础不在标准课程材料之内。本文的其中一个目的是提供额外的基础。

图 7 显示了业务模型中所找到的东西和系统用例模型中的东西之间的清晰映射。在此特殊的实例中,可以看出,系统能够将业务角色的职责自动化。它还显示出关键的业务角色是自动化的候选者。

记住,业务模型包含业务用例模型和业务分析模型。业务分析模型是业务用例模型的实现,并且拥有紧密的集成化和可追溯性。系统用例模型可以追溯到业务分析模型。业务分析模型可以追溯到业务用例模型。

使用该方法,您可以构建从业务分析模型演化来的系统用例模型。这向您的整个 UML 模型提供了一致性和可追溯性。

那么系统参与者和系统用例从那里来的呢?系统参与者是根据业务分析模型中的业务参与者和业务角色而生成的。与业务角色自动化候选者交互的业务参与者总是成为系统参与者。不是自动化候选者的,与业务角色自动化候选者交互的业务角色成为系统参与者。例如,ISM 业务分析模型中的执法人和法院成为了系统参与者。ISM Broker 是“纯”自动化候选者。它不会成为系统参与者。

我所谓的纯是什么意思呢?简单的说,自动化候选者的唯一目的就是成为我们正在开发的软件解决方案的代理。注意到图 7 中的 Loan Specialist。Loan Specialist 业务角色转换为系统参与者和系统用例。让我来解释一下。

Loan Specialist 是图 7 中所示的业务模型中的角色。在我们的系统用例模型中,需要有作为 Loan Specialist 角色的参与者。但是,在我们正在开发的新的软件解决方案中将 Loan Specialist 的一些业务职责自动化了。业务分析模型中的那些业务职责成为了系统用例模型中的系统用例。

其他的纯业务角色自动化候选者将不会转换为系统用例模型中的系统角色。这回答了问题,“系统用例是从哪里来的?”系统用例是根据业务分析模型中的业务角色自动化候选者的业务职责而创建的。如果您回到图 5,显示了 ISM Broker 的 VOPC 图,每个业务职责,例如 Query for Information,都可以转换为系统用例模型中的系统用例。

分析模型显示了业务实体如何映射到系统分析模型中的类上。这些类表示系统将使用的“数据”。

总结

我的目标是概括出 RUP 业务建模和系统用例建模的比较情况。我讨论了相似点和差别,以及业务用例模型和系统用例模型之间的关系。如果您对这些比较和关系有任何疑问,可以通过 arthur.english@unisys.com 联系我。

注释

1用例视图(Use-Case View)、逻辑视图(Logical View)是 UML 4+1 视图模型架构(UML 4+1 View Model Architecture)的一部分。要了解更多关于 4+1 视图模型架构的信息,您应该学习分析与设计规程中的 URUP 软件架构概念。

使用 UML 进行业务建模:理解业务用例与系统用例的相似和不同之处的更多相关文章

  1. 基于 UML 的业务建模举例

    简介: 对于管理流程咨询项目.大型信息化建设项目和套装管理软件实施项目,对业务环境的分析和理解对项目的成功至关重要.系统.全面理解 IT 系统所处的业务环境,可以帮助 IT 系统能提供正确系统功能,并 ...

  2. 【DDD】领域驱动设计实践 —— 业务建模小招数

    本文结合团队在ECO(社区服务系统)业务建模过程中的实践经验,总结得到一些DDD业务建模的小招数,不一定是完美的,但是对我们团队来说很有效用,希望能帮到其他人.后面会陆续将项目中业务建模的一些经典例子 ...

  3. 【DDD】领域驱动设计实践 —— 业务建模实例(‘发布帖子’)

    本文是基于上一篇‘业务建模小招数’的实践,后面的多篇博文类似.本文主要讲解‘发表帖子’场景的业务建模,包括:业务建模.业务模型.示例代码:示例代码会使用java编写,文末附有github地址.相比于& ...

  4. 【DDD】业务建模实践 —— 删除帖子

    本文是基于上一篇‘业务建模战术’的实践,主要讲解‘删除帖子’场景的业务建模,包括:业务建模.业务模型.示例代码:示例代码会使用java编写,文末附有github地址.相比于<领域驱动设计> ...

  5. 【DDD】业务建模实践 —— 发布帖子

    本文是基于上一篇‘业务建模战术’的实践,主要讲解‘发表帖子’场景的业务建模,包括:业务建模.业务模型.示例代码:示例代码会使用java编写,文末附有github地址.相比于<领域驱动设计> ...

  6. 【DDD】领域驱动设计实践 —— 业务建模战术

    本文结合团队在COMMUNITY(社区服务系统)业务建模过程中的实践经验,总结得到一些DDD业务建模的小招数,不一定是完美的,但是对我们团队来说很有效用,希望能帮到其他人.后面会陆续将项目中业务建模的 ...

  7. UML精粹4 - 对象图,包图,部署图,用例

    对象图object diagram 对象图是某个时间点上的对象在系统中的快照,也经常被称为实例图.一般在展示组合对象结构时比较有用.例如 组合结构的类图 一个时刻的对象图 包图package diag ...

  8. 直播开始:'云榨汁机'诞生记--聊聊JavaScript中的'业务建模'

    闭包是JavaScript中的一个重要特性,在之前的博文中,我们说闭包是一个'看似简单,其实很有内涵'的特性.当我们用JavaScript来实现相对复杂的业务建模时,我们可以如何利用'闭包'这个特性呢 ...

  9. 【DDD】业务建模实践 —— 人关注人

    社区业务领域中,存在‘人关注人’的场景,在这个场景中,关系较为复杂,且均表现在‘人’同一个业务实体上,因此,这个case的建模过程值得思考.本文将就‘人关注人’这个业务case的领域建模进行探讨,欢迎 ...

随机推荐

  1. heap creation

    There two methods to construct a heap from a unordered set of array. If a array has size n, it can b ...

  2. C# linq to xml

    XDocument doc = new XDocument( new XDeclaration("1.0", "utf-8", "yes") ...

  3. Haffman算法(C++)

    Huffman编码,C++实现,只是为了说明大致的思路,还有很多不完美之处,比如在输入数据超出限制等条件下会出现错误. #include<iostream> #include<str ...

  4. Eclipse 浏览文件插件- OpenExplorer

    http://blog.csdn.net/w709854369/article/details/6599167 EasyExplorer  是一个类似于 Windows Explorer的Eclips ...

  5. iOS极光推送的基本使用

    昨天花了一下午的时间研究了下极光推送,也前也是没做过,不知道从何下手!才开始的时候一看官方的SDK感觉好难,不过经过一系列的捣鼓之后,手机收到了推送信息,感觉其实并没有那么难! 1.配置开发证书(得有 ...

  6. javascript中对象的不同创建方法

    javascript中的对象与一般的面向对象的程序设计语言(c++,Java等)不同,甚至很少有人说它是面向对象的程序设计语言,因为它没有类.javaScript只有对象,不是类的实例.javascr ...

  7. JVM学习之Eclipse输出GC日志

    Java应用启动时,可以通过设置verbose参数来输出JVM的gc情况,命令如下:-verbose:gc或者-XX:+PrintGC在Eclipse中可以通过Run As|Run Configura ...

  8. eclipse 异常Unhandled event loop exception

    出了这一类的异常问题,大都是一些图像优化软件插件等等. 出现的问题大都是,一些eclipse模块不显示,或者点击不反应,出现最多的次数是点击断点的时候. 我这里是Catalyst Control Ce ...

  9. Python进阶之闭包

    闭包 .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB","S ...

  10. Moutain Tai notes

    rest 40shaxian 18 drumsticks  13零食 11.5+21车费5门票62大衣10面14 > 194.5 notes :::: 岗位职责:1.基于Drupal系统的产品功 ...