packagefactory/atomicfusion-presentationobjects

允许在Atomic Fusion中使用类型安全的、可测试的展示对象(例如值对象)作为props和propsets的替代。

v4.0.0 2022-11-16 14:27 UTC

README

CI

PackageFactory.AtomicFusion.PresentationObjects

允许在Atomic Fusion中使用类型安全的、可测试的展示对象(例如值对象)作为props和propsets的替代。

安装

composer require packagefactory/atomicfusion-presentationobjects

文档

注意:您正在阅读3.0版本的README!您可以在这里找到2.0版本的README:这里

  1. 展示对象和组件
  2. 通过展示对象工厂的内容集成
  3. 插槽
  4. 集成食谱
  5. 使用组件启动器进行脚手架搭建
  6. 预览模式

原因

PackageFactory.AtomicFusion是Neos CMS组件架构方向的第一步。它提供了一个Component融合原型,允许编写具有清晰后端接口的前端组件。

然而,这个接口并不严格。开发者可以表达他们组件的需求,但这些需求在任何层面上都没有被强制执行。因此,创建了PackageFactory.AtomicFusion.PropTypes来将React.js PropTypes的概念引入AtomicFusion。

PropTypes在组件被调用时对传入的数据与定义的方案进行比较,从而确保组件永远不会用无效的数据渲染。这种模式的弱点是,对组件接口完整性的任何保证都只能在运行时进行。因此,集成仍然存在错误风险。

随着Typescript的出现,PropTypes在React世界中几乎已经过时,因为静态类型对包大小没有影响,并且可以在运行前捕获类型相关的错误。Typescript是ECMAScript的超集,通过类型注解扩展了语言。到目前为止,Fusion还没有类似的概念。

这就是展示对象发挥作用的地方。

展示对象的想法是利用PHP的类型系统通过用实际的PHP接口替换动态的array-driven props来强制执行组件接口。PackageFactory.AtomicFusion.PresentationObjects确保传递给该组件的任何对象都实现了声明的接口。

它是如何工作的?

此包提供了一种特殊的Fusion组件原型,允许通过@presentationObjectInterface注解将组件与PHP接口关联起来。PackageFactory.AtomicFusion.PresentationObjects确保任何传递给该组件的对象都实现了声明的接口。

展示对象是值对象(请参阅:https://martinfowler.com.cn/bliki/ValueObject.html)。它们是不可变的,并且只能包含标量属性、其他值对象或前两者的数组。它们作为可预测的数据容器。

展示对象由工厂创建(请参阅:https://en.wikipedia.org/wiki/Factory_(object-oriented_programming))。这些类负责封装组件的特定用例,检索生成它所需的所有数据,并进行所需的数据映射。为了在Fusion中访问它们,展示对象工厂被注册为Eel Helper。

好处

类型安全和静态分析

PresentationObjects最重要的功能是利用PHP的类型系统,在领域层和表示层之间强制执行接口。然而,如果没有进一步措施,PHP的类型系统仅在运行时相关。

幸运的是,有像phpstanpsalm这样的工具,它们允许对您的PHP代码库进行静态分析。

类型安全性和静态分析带来许多好处

  1. 在运行时之前捕获类型相关的错误。连续使用Typehints确保在静态分析期间代码的正确性。使用phpDoc类型甚至可以让您使用泛型或联合类型等模式,而无需PHP类型系统实际支持它们。
  2. 自文档化的接口。类型提示和类型注释通过在参数和属性上添加所需数据类型的重要信息,而不需要查找单独的文档来修正。
  3. IDE支持。现代PHP IDE可以理解Typehints和phpDoc类型,并可以使用它们提供代码补全、智能参数建议和高级重构功能。

测试与QA工具

由于它们只是PHP代码,因此使用phpunit (https://phpunit.de/)等工具为PresentationObjects和PresentationObject工厂编写功能测试和单元测试相当容易。

出于同样的原因,PresentationObjects与PHP的任何QA工具(如)很好地集成

关注点分离

Fusion的可扩展性通常是一个很好的特性,但在处理复杂的数据处理任务时,它也会导致模糊性。

您有几种选择来封装有效任务(例如,自定义Eel-Helpers、自定义FusionObjects、自定义FlowQueryOperations、Neos.Neos:Plugin等),但没有真正指导哪种机制适合哪种用例。

当使用PackageFactory.AtomicFusion.PresentationObjects时,数据内容集成由PresentationObject工厂明确处理。由于这些是能够在Neos实例内执行任何数据操作的PHP类,因此您选择的机制归结为一个选项。

调试

Fusion有时很难调试,尤其是当不清楚故障发生的确切位置时。Neos.Fusion:Debug不能随意放置在您的Fusion代码中,需要像其他一切一样渲染。因此,它还要求渲染过程完全成功。

Presentation对象工厂允许使用经典的\Neos\Flow\var_dump(); die;调试模式进行简单调试。

对于更高级的需求,PresentationObjects的PHP原生特性与Xdebug步骤调试(《https://xdebug.org/docs/remote》)和性能分析(《https://xdebug.org/docs/profiler》)具有天然兼容性。

缺点

远离Neos.Fusion

Fusion是一种专门针对声明性渲染指令的领域特定语言。作为DSL,Fusion能够在语言层面上强制执行某种思维方式。

PresentationObjects将内容集成的关注点在很大程度上转移到PHP。虽然PHP是一种多范式语言,可以像Fusion一样使用,但它根本不强制执行这种使用。

因此,当使用 PackageFactory.AtomicFusion.PresentationObjects 时,您需要注意您的语言使用并避免常见的反模式。强烈建议您在编写PresentationObjects时严格遵守值对象模式。对于工厂,熟悉通用的PHP最佳实践很有帮助(例如,请参阅:https://phptherightway.com/)。

提示: PHP 8 即将发布,并带来了许多优秀的语言特性,这将使您能够以更简洁的方式编写这里展示的大多数模式。特别值得一提的是 构造器属性提升命名参数。有关更多信息,请参阅这篇文章:https://stitcher.io/blog/new-in-php-8

冗长性

PresentationObjects要求您比AtomicFusion编写更多的代码。为此,此包提供了一个脚手架工具,以简化初始代码结构的创建。

目前,还涉及许多概念,这些概念在代码库中分散信息(Classes/Presentation/Resources/Private/Fusion/Configuration/),从而打破了邻接原则。

理论上,可以通过利用composer清单中的autoload.psr-4配置来实现邻接(请参阅:https://getcomposer.org.cn/doc/04-schema.md#psr-4)。然而,这个想法的可行性尚未得到证实。有关如何实现邻接的更多信息,请参阅Kickstarter部分

Fusion交互

到目前为止,Fusion仍然是内容集成的人口点。这一点很重要,尤其是在更改工厂方法签名时,因为这是一个大型表面,在这里类型安全性会丢失。

Fusion需要处理两个主要问题

  1. Neos CMS的内联内容映射和增强逻辑。 Neos使用Fusion将内容存储库节点映射到其相应的渲染指令。它还使用Fusion来增强渲染内容元素,以便Neos UI能够进行内联编辑。
  2. 内容缓存和部分页面渲染。 Fusion提供了@cache注解,以启用不同渲染路径的单独缓存指令。其ContentCache服务能够解决嵌套的缓存和非缓存页面片段,从而实现最大的灵活性。

本包的未来发展将专注于解决这两个问题的解决方案。

贡献

我们乐于接受贡献。请向我们发送拉取请求。

许可

请参阅LICENSE