软件架构中的模块化方法可以将项目逻辑上划分为较大的组成部分(模块)。
模块的标志是它的自足性,在某种意义上,它是在单体应用中划分 "微服务" 的一种形式。
与微服务的主要区别在于,模块必须通过预定义的契约交换数据,这些契约取代了 HTTP API(或消息代理),并且模块共享用于路由、服务和来自 /vendor/ 目录的外部库的公共文件夹。
建议设计契约时,使其在需要时能够将模块提取为一个完整的微服务。
在 HLEB2 框架中,模块本质上是一个小型的 MVC(Action-Domain-Responder 用于 Web)。 模块有自己的控制器、自己的模板文件夹,甚至可以有自己的配置,这些都位于模块的文件夹中。 模块还可以有自己的逻辑(以及模型),但为此,建议在项目的 /app/ 文件夹或模块内部创建一个单独的结构。
在项目中使用完全自主的部分时,这就是模块化开发的本质,您可以完全不使用来自 /app/ 的控制器、中间件和模型,并在模块中实现一切功能。
模块控制器在路由中的作用与普通控制器不同,方法名称为 'module',而不是 'controller',并且包含一个额外的初始参数,即模块名称。
模块的控制器必须继承自 Hleb\Base\Module。
为了让 Composer 类加载器为模块生成类映射,请在 /composer.json 文件的 "autoload" > "classmap" 部分中添加模块文件夹名称 ("modules/")。
使用控制台命令创建模块基本结构的简单方法:
$php console --create module example
此命令将在项目的/modules/example/目录中创建一个新的模块模板。 您可以为模块使用另一个合适的名称,由小写拉丁字母、数字、破折号和 '/' 符号(表示嵌套)组成。 可以选择重写生成过程中使用的原始模块文件。
创建后的模块结构(如果之前没有modules文件夹,控制台命令将在项目根目录创建它):
main.php 文件可以包含类似于/config/main.php文件的设置,但使用仅在模块中使用的值,这意味着它将“覆盖”它们。
最初,main.php 文件不包含任何设置;使用所有来自/config/main.php的设置。
同样,通过创建同名文件,可以替换/config/database.php的设置。
其他配置文件的设置始终全局有效。
模块控制器类似于框架的标准控制器。 使用view()函数时,模板路径将指向模块的'views'文件夹,就像框架的所有内置模板工作函数一样。
有一个选项可以将模块分组到不同的/modules/子文件夹中的集合。 为此,模块放置在更低的一级,并且模块名称包含组名称。 这构成了模块嵌套的第二级。
假设我们需要放置一个名为'main-product'的模块组,其中将包含模块'first-feature' 和 'second-feature'。
这就是它在路由图中的样子:
在名为 'first-feature' 的组中,重新分配了设置,包括对数据库的设置。
'second-feature' 的示例使用了全局设置,另外,它还有一个给控制器的 middleware。
可能会有更多的控制器在此出现。
如果需要,可以为第三层嵌套创建一个结构。
最初,模块文件夹称为 'modules';在创建模块之前,可以在设置中更改该名称,例如更改为 'products'。
这是在 /config/system.php 文件中完成的 - 设置 'module.dir.name'。
如果是在已存在的模块类的情况下进行更改,则需要为符合 PSR-0 的模块修正 namespace。
在模块中,可以重写两个配置文件 - /config/main.php 和 /config/database.php。
参数值按键递归重写,否则,参数具有全局值。没有全局对照的新参数将在模块中本地可用。
当使用模块作为单独的包时,不总是需要包中包含 View 模板,因为样式和结果输出可能是应用程序结构中的单独层。
因此,对于使用模板可以有两种选择。
“使用”指的是在 view() 函数中的模板指针以及像 insertTemplate() 这样的特殊函数。
如果模块中有 /views/ 文件夹,模板路径将指向该文件夹。
但如果没有这样的文件夹,模板搜索将发生在项目的 /resources/views/ 目录中。