基于模型生成和配置应用程序

您可以从模型生成或配置应用程序的各部分。可以是 UML 或 DSL 形式的模型。

模型比代码更能直接表示需求。与更新代码相比,通过直接从模型派生应用程序的行为,您可以更加快速可靠地对更改的需求做出响应。尽管需要一些初始操作来设置派生,但如果您预期需求会发生改变,或者您计划生成产品的几个变体,则这种投资是会有回报的。

从模型生成应用程序代码

生成代码的最简单方法是使用文本模板。您可以在保留模型的 Visual Studio 解决方案中生成代码。有关更多信息,请参见:

此方法便于增量应用。首先使用一个仅适用于特定情况的应用程序,并从模型中选择一些您希望更改的应用程序部分。重命名这些部分的源文件,以便这些文件成为文本模板 (.tt) 文件。此时,将自动从模板文件生成 .cs 源文件,该应用程序能像以前一样工作。

然后,您可以采用一部分代码并将其替换为文本模板表达式,该表达式读取模型并生成这部分的源文件。至少模型的一个值应生成原始源,这样您才能再次运行该应用程序,该应用程序才能像以前一样工作。在测试过不同的模型值之后,您可以继续在另一部分代码中插入模板表达式。

这种递增方法意味着代码生成通常是一种低风险的方式。生成的应用程序通常能执行与手写版本几乎一样的操作。

但是,如果是从一个现有应用程序开始的,您可能会发现需要进行很多重构才能隔开受模型控制的不同行为,以便这些行为可以独立改变。建议您在估计项目成本时,将应用程序的这一方面评估在内。

从模型配置应用程序

如果您希望在运行时改变应用程序的行为,则无法使用在编译应用程序前生成源代码的代码生成。相反,您可以将应用程序设计为读取 UML 或 DSL 模型并相应地改变其行为。有关更多信息,请参见:

也可以增量应用此方法,但开头会有更多的工作要去做。您需要编写代码来读取模型,并设置一个允许可变部分访问其值的框架。生成泛型的可变部分比代码生成的开销更大。

一个泛型应用程序的执行效果通常没有其特定的对应应用程序好。如果性能很关键,则您的项目计划应将这种风险评估在内。

开发派生应用程序

您可能会发现以下一般准则会很有帮助。

  • **先具体后一般化。**首先编写一个特定版本的应用程序。此版本应能在一组条件下工作。当您认为该应用程序能正常工作时,您可以从模型派生一些部分。逐渐扩展派生的部分。

    例如,设计一个具有一组特定网页的网站,然后设计一个 Web 应用程序来表示在模型中定义的页面。

  • **建立可变方面的模型。**确定将发生改变的方面,两个不同部署之间的改变,或随着需求变化而改变。这些方面应从模型派生。

    例如,如果一组网页及其之间的链接发生更改,但这些网页的样式和格式始终是相同的,那么模型应描述这些链接,但不必描述网页的格式。

  • **任务分离。**如果可变方面能分成独立的区域,则为每个区域使用单独的模型。使用 ModelBus,您可以定义同时影响各模型及其之间的约束的操作。

    例如,使用一个模型来定义网页导航,使用另一个模型来定义网页布局。有关更多信息,请参见如何:将 UML 模型与其他模型和工具集成

  • **建立需求而非解决方案的模型。**设计 DSL 或采用 UML,以便用来描述用户需求。与此相反,不要根据实现的可变方面设计表示法。

    例如,Web 导航模型应表示网页和网页间的超链接。Web 导航模型不应表示应用程序中的 HTML 或类的片段。

  • **生成或解释?**如果特定部署的需求将很少更改,则从模型生成程序代码。如果需求可能会频繁更改,或者可能共存于同一部署的多个变体中,则编写应用程序,以便该应用程序可以读取和解释模型。

    例如,如果您使用网站模型来开发一系列独立安装的不同网站,则应从模型生成网站代码。但如果您使用模型来控制一个每天改变的网站,则最好编写一个 Web 服务器来相应地读取模型和表示网站。

  • **UML 或 DSL?**考虑通过使用构造型扩展 UML 来创建您的建模表示法。如果没有符合目标的 UML 关系图,则定义一个 DSL。但要避免中断 UML 的标准语义。

    例如,UML 类图是框和箭头的集合;有了这种表示法,您在理论上能定义任何内容。但是,除非您实际需要描述一组类型,否则我们不建议您使用类图。例如,您可以采用类图来描述不同类型的网页。

请参见

概念

如何:从 UML 模型生成文件

如何:在程序代码中读取 UML 模型

如果:在程序代码中从文件打开模型

使用 T4 文本模板生成设计时代码

其他资源

从域特定语言生成代码