这不是一个特定的已知设计模式,它是专门为 oxid 设计的功能。Oxid 中的类不是用“new”而是由工厂实例化的,例如 oxnew("oxarticle")。如果 oxarticle 没有注册的模块,工厂只返回一个 oxarticle 的实例。
当一个模块将“myOxarticle”注册为 oxarticle 的扩展时,oxnew("oxarticle") 将返回一个 myOxarticle 实例,而 myOxarticle 将从 oxarticle 扩展而来。这个类链是工厂搭建的。这是第一个好处,假设您使用了“myOxarticle extends oxarticle”,您将不得不更改所有使用 oxarticle 的地方,以便使用您的对象而不是 oxarticle。现在有了透明的类链,工厂处理了这个,你的新功能现在可以在任何使用 oxarticle 对象的地方使用。调用 oxnew("oxarticle") 的地方不需要知道你的新对象。
第二个优点是当有多个模块扩展同一个 Oxid 类,甚至是同一个方法时。工厂在后台构建类链,oxnew("oxarticle") 返回链中最后一个类的实例。如果扩展一个类,则在所有方法中调用父方法是一种很好的做法。因此,如果调用基类的某个方法,则所有模块类的每个方法都会被执行,并且每个模块都不需要知道其他模块。
另一种扩展功能的方法是使用钩子或过滤器。钩子的缺点是它们必须内置到每个可能扩展的方法中,即使这样,氧化方式也更加灵活。
可能有一些原因会阻止您在类方法中调用父方法,例如,如果父方法做了您不希望发生的事情。在这种情况下,这破坏了模块之间的独立性,并且只有在没有其他方法的情况下才应该这样做。
如果您不想更改现有行为,而是想创建自己的仅由模块使用的类,例如新的页面控制器,则元数据中有“文件”数组,它只在自动加载器,在这种情况下,您将使用例如“mycontroller extends oxubase”而不是“mycontroller extends mycontroller_parent”。