Child class 监听静态父方法
Child class listening to static parent method
我很确定我的问题已经在某个地方得到了回答,但我似乎找不到答案,所以我在这里试试。
有没有办法让子 class 监听其父 class 的静态方法并执行其中一个静态方法?或者它应该使用一个接口,如果是这样,你会怎么做?
最好的例子是命令 class:你有那个:
class Command {
public static function execute($name, $args) {
// Do something
}
}
当您调用该方法执行时,所有子class都会查看名称是否与其名称相对应。
class Subcommand extends Command {
public static $name = "command";
public static function execute($name, $args) {
if (self::$name === $name) {
// Do something
}
}
}
问题是必须有多个 classes,例如 Subcommand,我不想手动调用所有这些,应该有一些东西可以自动执行。
现在,我只是像这样在命令 class 中放置了一个数组:
$commands = [
Subcommand1::class,
Subcommand2::class,
Subcommand3::class
// …
]
然后我遍历它并调用每个子程序的执行方法class,但我希望可以有更优雅的方法来实现它。
实际上,我认为您当前的方法是优雅的方法(请参阅 Command 设计模式)。
据我了解,您要实现的是执行 Command
的所有已注册子 类 的方法。这至少有两点不优雅。 首先,你必须从所有声明的类(使用get_declared_classes
)中过滤掉你的sub类。这可能非常详尽。 其次,在这种情况下,您可以通过添加或删除命令来控制要执行的命令数量类。这实际上违背了 OOP 的目的(Object-Oriented Programming,而不是 Class-Oriented Programming)。程序的流程应该由对象的交互来定义。
execute()
的 $name
参数感觉需要在此处检查:
- 它的有效值是多少? (它是完全自由形式的,还是从一些枚举中选择的?)
- 它们与子命令有什么关系? (一对一?一对多?多对多?)
- 调用者如何选择?
我很想说 execute()
的调用者不应该传递该信息;如果它知道要使用哪个命令,它应该构造一个表示该命令的对象。
如果每个名称都与一个子命令一一对应,那么调用者只需实例化该子命令即可class。如果它是一对多或多对多关系,您将需要一些额外的 "command type" classes;或者您可以每次构造相同的对象,但带有它应该分派到的子命令列表。
您可能还需要一个工厂方法,它给定命令的名称,并构造一个适当的子命令或命令类型。这允许命令的选择是动态的,例如从用户输入,并保持任何复杂的逻辑关于在一个地方创建什么对象。这可能是一个硬编码的 switch 语句,您可以在其中管理所有名称到 class 的关系,或者它可以是一个注册表,新的子 classes 可以在其中注册特定的命令名称。
最后一种情况本质上是观察者模式:命令名称是事件,子class已经注册观察它们。由于 sevavietl
这使得关系更加明确:如果 class 实际上未在任何地方列出,则 class 的存在通常不应触发行为。这在 PHP 中尤其如此,其中 classes 通常仅在首次引用时才在磁盘上查找,因此您在 运行 时实际上不知道有多少 classes 你的项目包含。
我很确定我的问题已经在某个地方得到了回答,但我似乎找不到答案,所以我在这里试试。
有没有办法让子 class 监听其父 class 的静态方法并执行其中一个静态方法?或者它应该使用一个接口,如果是这样,你会怎么做?
最好的例子是命令 class:你有那个:
class Command {
public static function execute($name, $args) {
// Do something
}
}
当您调用该方法执行时,所有子class都会查看名称是否与其名称相对应。
class Subcommand extends Command {
public static $name = "command";
public static function execute($name, $args) {
if (self::$name === $name) {
// Do something
}
}
}
问题是必须有多个 classes,例如 Subcommand,我不想手动调用所有这些,应该有一些东西可以自动执行。
现在,我只是像这样在命令 class 中放置了一个数组:
$commands = [
Subcommand1::class,
Subcommand2::class,
Subcommand3::class
// …
]
然后我遍历它并调用每个子程序的执行方法class,但我希望可以有更优雅的方法来实现它。
实际上,我认为您当前的方法是优雅的方法(请参阅 Command 设计模式)。
据我了解,您要实现的是执行 Command
的所有已注册子 类 的方法。这至少有两点不优雅。 首先,你必须从所有声明的类(使用get_declared_classes
)中过滤掉你的sub类。这可能非常详尽。 其次,在这种情况下,您可以通过添加或删除命令来控制要执行的命令数量类。这实际上违背了 OOP 的目的(Object-Oriented Programming,而不是 Class-Oriented Programming)。程序的流程应该由对象的交互来定义。
execute()
的 $name
参数感觉需要在此处检查:
- 它的有效值是多少? (它是完全自由形式的,还是从一些枚举中选择的?)
- 它们与子命令有什么关系? (一对一?一对多?多对多?)
- 调用者如何选择?
我很想说 execute()
的调用者不应该传递该信息;如果它知道要使用哪个命令,它应该构造一个表示该命令的对象。
如果每个名称都与一个子命令一一对应,那么调用者只需实例化该子命令即可class。如果它是一对多或多对多关系,您将需要一些额外的 "command type" classes;或者您可以每次构造相同的对象,但带有它应该分派到的子命令列表。
您可能还需要一个工厂方法,它给定命令的名称,并构造一个适当的子命令或命令类型。这允许命令的选择是动态的,例如从用户输入,并保持任何复杂的逻辑关于在一个地方创建什么对象。这可能是一个硬编码的 switch 语句,您可以在其中管理所有名称到 class 的关系,或者它可以是一个注册表,新的子 classes 可以在其中注册特定的命令名称。
最后一种情况本质上是观察者模式:命令名称是事件,子class已经注册观察它们。由于 sevavietl
这使得关系更加明确:如果 class 实际上未在任何地方列出,则 class 的存在通常不应触发行为。这在 PHP 中尤其如此,其中 classes 通常仅在首次引用时才在磁盘上查找,因此您在 运行 时实际上不知道有多少 classes 你的项目包含。