模块化 组合化
这是本系列的第二篇文章,介绍了用于组合的反转控制类型系统。 本文讨论了比上一篇文章的“一流过程类型”更通用的“模块类型”系统。
注意:某些功能性编程语言也尝试定义一流模块。 本文定义的First-Class Modules是从反向函数创建的。
一流的程序
回顾上一篇文章 ,First-Class Procedure的类型定义如下。 请注意,由于依赖项是自动关联的,因此我们排除了依赖项类型。
FirstClassProcedureType {
Class<?> parameterType;
ContinuationType[] continuations; } ContinuationType {
String name;
Class<?> argumentType; }
这就定义了First-Class Procedure具有单个输入参数和多个连续输出,以进一步构成逻辑和处理异常。
模组
对于具有第一类过程的方法,函数等而言,具有一个具有多个输出的单个输入是很好的选择。 但是,当系统增长时,我们不希望复杂度使输入/输出遭受类似的复杂度增加。 我们希望输入/输出提供一个接口来封装模块的复杂性。 请注意,如果没有封装,我们将无法模块化应用程序的复杂性。
要启用到模块的接口,让我们创建以下输入/输出类型:
InputType {
String name;
Class<?> parameterType; } OutputType {
String name;
Class<?> argumentType; }
为了理解为什么要创建这些类型,我们将使用耦合控制反转的可视化配置来更好地帮助理解正在发生的事情。
以下模块配置代表由First-Class Procedure处理并将其结果发送到输出的单个输入:
在以上配置中,First-Class Procedure封装在模块中。 模块公开的全部是输入和输出。 上述模块的结果类型如下:
- 输入名为“输入”,并将参数传递给第一类过程
- 名为“ Output”的输出,其参数由First-Class Procedure执行的结果提供
但是,这在First-Class Procedure接口上没有什么改进。
有用的是封装多个First-Class Procedures以承担模块的功能:
尽管模块中包含了新的过程,但模块的界面没有变化。 使用该模块的其他配置将不会意识到在内部添加了另一个First-Class Procedure。
我们也不必将自己局限于单个输入和输出。 我们可以有一个具有多个输入和输出的任意复杂的模块:
生成的模块封装了详细信息以具有以下接口:
- 输入“输入”
- 输入“ Input-2”
- 输出“输出”
- 输出“ Output-2”
- 输出“ Output-3”
模块类型
模块的结果类型如下:
SectionType {
InputType[] inputs;
OutputType[] outputs }
请注意, OfficeFloor的命名源自其在业务概念中的基础,随后将模块称为“部分”。
模块(部分)具有多个输入和多个输出。 然后可以将这些输入/输出连接到其他模块的相应输出/输入。
此外,模块本身可能包含其他模块。 连接输入/输出以进行合成时,模块具有与一流程序相同的输入/输出连接。 以下配置演示了将本文开头的模块嵌入另一个模块中:
在上面的配置中,封装的模块是包含单个First-Class Procedure还是两个First-Class Procedure都是无关紧要的。 仅在模块公开的输入/输出上使用模块。 模块的其余复杂性都被封装。 这允许模块化应用程序的复杂性。
一流的模块
因此标题提到了“一流的模块”,但我们只是在视觉上讨论了将模块连接在一起的问题。
为了本质上成为“一流”,需要将模块分配给变量。
上面的图形配置是建立在以编程方式一起配置的Sections(模块)之上的。 图形配置实际上是在First-Class Modules(部分)之上的一层,以使您更容易理解应用程序的模块化方式。
您可以在本文上面使用的OfficeFloor的图形配置实现中看到这一点。 上面的图形配置是通过活动进行的。 Activity是Section的特定专业化( ActivityLoaderImpl源在此处 )。 该活动将XML从图形配置转换为创建节,一流过程,输入,输出。 Activity实现中的每个变量都分配给变量,存储在数据结构中,传递给函数,从函数返回等。这使Section(模块)本质上是“一流的”。
这种基于延续的输入/输出接口非常灵活。 它是如此之多,以至于First-Class Procedures本身也只是Section的专门实现( 请参阅ProcedureEmployer )。
摘要
我们已经看到了如何将First-Class Procedures封装在First-Class Modules中,甚至是First-Class Modules自身中。
我们已经展示了图形配置实际上是如何利用“一流”特性的。 图形配置实际上是一个较高层次的组合,它提供以下两个方面:
- 更容易理解应用程序的模块化
- 更快地配置应用程序(实际上只是画线以进行合成)
请注意,以编程方式配置我们的应用程序是很有可能的。 但是,这需要更深入地了解一流程序/模块。 最初,初级开发人员可能不希望这样做。
因此,一流模块的图形化配置为构建模块化应用程序提供了简便性。 这无需处理基础结构的复杂性。 我发现其他构图策略仍存在问题。
在下一篇文章中,我们将讨论一流模块如何提供各种现有组合策略的组合。 您可能会发现,现有的组合策略实际上只考虑了小型编程,而不是考虑大型编程,因为一流模块在模块化和简化应用程序方面变得更加有效。
翻译自: https://www.javacodegeeks.com/2020/01/first-class-module-type-system-for-composition.html
模块化 组合化