透明父 classes 扩展基础 class vs "normal" 扩展基础 class
Transparent parent classes to extend base class vs "normal" extension of a base class
我是 Oxid 框架的新手,它广泛使用透明父 classes 来扩展基础 class。我没有看到这种技术的优势。所以我很好奇,这是一种模式吗?好处在哪里?
干杯,
凯瑟琳
示例代码:
\ a class by the framework I like to extend
class A { ... }
比框架扩展此 class 的常用方法:
class B extend class B_parent
其中 B_parent 是由框架通过配置文件创建的 class,如下所示:
'extend' => array(
'A' => 'path_to/B')
OXID 使用这种方式处理 class 扩展,因为它可以在不破坏继承链的情况下为相同的 class 组合多个扩展。
例如你有两个扩展相同 class “start
” 的模块(用于商店起始页)
如果两个模块都使用 class myStart extends start
和 myOtherStart extends start
,它们将仅继承自 start
,并且没有其他扩展的附加功能或更改。所以你不能同时使用这两个模块。
通过使用 class myStart extends myStart_parent
和 myOtherStart extends myOtherStart _parent
以及 metadata.php 中的扩展映射,OXID 可以动态地将相同 class 的所有更改合并为一个 class.
1) start
是父级 class
2) myStart
将应用于 start
3) myOtherStart
将应用于 myStart
在此继承链的末尾,您将获得一个具有所有 class 扩展功能的 class
干杯!
这不是特定的已知设计模式,它是专为 oxid 设计的功能。 Oxid 中的 类 不是用 "new" 实例化的,而是由工厂实例化的,例如 oxnew("oxarticle")。如果没有为 oxarticle 注册的模块,工厂只是 return oxarticle 的一个实例。
当模块注册"myOxarticle"作为oxarticle的扩展时,oxnew("oxarticle")将return一个myOxarticle实例,而myOxarticle将从oxarticle扩展。此 class 链条由工厂制造。这是第一个好处,假设您使用了 "myOxarticle extends oxarticle",您将不得不更改所有使用 oxarticle 的地方,以便使用您的对象而不是 oxarticle。现在有了透明的 class 链,工厂会处理这个问题,你的新功能现在可以在任何使用 oxarticle 对象的地方使用。调用 oxnew("oxarticle") 的地方不需要知道你的新对象。
第二个优势是当有多个模块扩展相同的 Oxid class,甚至是相同的方法时。工厂在后台构建一个class链,oxnew("oxarticle")return是链中最后一个class的实例。如果您扩展 class,您最好在所有方法中调用父方法。因此,如果调用基 class 的某个方法,则所有模块 classes 的每个方法都会被执行,并且每个模块都不需要知道其他模块。
另一种扩展功能的方法是使用挂钩或过滤器。钩子的缺点是必须将它们内置到每个可能扩展的方法中,即使这样氧化方式也更灵活。
可能有一些原因阻止您在 class 方法中调用父方法,例如,如果父方法执行了您不希望发生的事情。在这种情况下,这会破坏模块之间的独立性,并且只有在没有其他可能的情况下才应该这样做。
如果您不想更改现有的行为,而是想自己构建仅供您的模块使用的 class,例如新的页面控制器,则 "files"元数据中的数组,仅在自动加载器中注册您的 class,在这种情况下,您将使用 "mycontroller extends oxubase" 而不是 "mycontroller extends mycontroller_parent".
我是 Oxid 框架的新手,它广泛使用透明父 classes 来扩展基础 class。我没有看到这种技术的优势。所以我很好奇,这是一种模式吗?好处在哪里?
干杯, 凯瑟琳
示例代码:
\ a class by the framework I like to extend
class A { ... }
比框架扩展此 class 的常用方法:
class B extend class B_parent
其中 B_parent 是由框架通过配置文件创建的 class,如下所示:
'extend' => array(
'A' => 'path_to/B')
OXID 使用这种方式处理 class 扩展,因为它可以在不破坏继承链的情况下为相同的 class 组合多个扩展。
例如你有两个扩展相同 class “start
” 的模块(用于商店起始页)
如果两个模块都使用 class myStart extends start
和 myOtherStart extends start
,它们将仅继承自 start
,并且没有其他扩展的附加功能或更改。所以你不能同时使用这两个模块。
通过使用 class myStart extends myStart_parent
和 myOtherStart extends myOtherStart _parent
以及 metadata.php 中的扩展映射,OXID 可以动态地将相同 class 的所有更改合并为一个 class.
1) start
是父级 class
2) myStart
将应用于 start
3) myOtherStart
将应用于 myStart
在此继承链的末尾,您将获得一个具有所有 class 扩展功能的 class
干杯!
这不是特定的已知设计模式,它是专为 oxid 设计的功能。 Oxid 中的 类 不是用 "new" 实例化的,而是由工厂实例化的,例如 oxnew("oxarticle")。如果没有为 oxarticle 注册的模块,工厂只是 return oxarticle 的一个实例。
当模块注册"myOxarticle"作为oxarticle的扩展时,oxnew("oxarticle")将return一个myOxarticle实例,而myOxarticle将从oxarticle扩展。此 class 链条由工厂制造。这是第一个好处,假设您使用了 "myOxarticle extends oxarticle",您将不得不更改所有使用 oxarticle 的地方,以便使用您的对象而不是 oxarticle。现在有了透明的 class 链,工厂会处理这个问题,你的新功能现在可以在任何使用 oxarticle 对象的地方使用。调用 oxnew("oxarticle") 的地方不需要知道你的新对象。
第二个优势是当有多个模块扩展相同的 Oxid class,甚至是相同的方法时。工厂在后台构建一个class链,oxnew("oxarticle")return是链中最后一个class的实例。如果您扩展 class,您最好在所有方法中调用父方法。因此,如果调用基 class 的某个方法,则所有模块 classes 的每个方法都会被执行,并且每个模块都不需要知道其他模块。
另一种扩展功能的方法是使用挂钩或过滤器。钩子的缺点是必须将它们内置到每个可能扩展的方法中,即使这样氧化方式也更灵活。
可能有一些原因阻止您在 class 方法中调用父方法,例如,如果父方法执行了您不希望发生的事情。在这种情况下,这会破坏模块之间的独立性,并且只有在没有其他可能的情况下才应该这样做。
如果您不想更改现有的行为,而是想自己构建仅供您的模块使用的 class,例如新的页面控制器,则 "files"元数据中的数组,仅在自动加载器中注册您的 class,在这种情况下,您将使用 "mycontroller extends oxubase" 而不是 "mycontroller extends mycontroller_parent".