子类听静态父方法

时间:2018-02-12 23:58:59

标签: php static-methods

我很确定我的问题已在某个地方得到解答,但似乎我找不到答案,所以我试试。

子类是否有办法监听其父类的静态方法并执行其静态方法之一?或者它应该使用接口,如果是这样,你会怎么做?

最好的例子是Command类:你有:

class Command {
    public static function execute($name, $args) {
        // Do something
    }
}

当你调用该方法执行时,所有子类都会看到name是否与其名称相对应。

class Subcommand extends Command {
    public static $name = "command";

    public static function execute($name, $args) {
        if (self::$name === $name) {
            // Do something
        }
    }
}

事情是必须有多个类,如子命令,我不想手动调用所有这些类,应该有一些事情可以自动完成。

现在,我只是在Command类中添加一个数组:

$commands = [
    Subcommand1::class,
    Subcommand2::class,
    Subcommand3::class
    // …
]

我迭代它并调用每个子类的execute方法,但我希望可以有更优雅的东西来实现它。

2 个答案:

答案 0 :(得分:1)

实际上,我认为您当前的方法是优雅的(看Command设计模式)。

据我了解,您要实现的是执行Command的所有已注册子类的方法。至少两点 不优雅首先,您必须从所有声明的类中过滤掉您的子类(使用get_declared_classes)。这可能非常详尽。 其次,在这种情况下,您只能通过添加或删除类来控制要执行的命令数。这实际上违背了OOP(对象 - 面向编程,而非面向类编程)的目的。程序的流程应该由对象的交互来定义。

答案 1 :(得分:0)

$name的{​​{1}}参数感觉需要在此检查:

  • 它的有效值是多少? (它是完全自由形式,还是从某些枚举中选择的?)
  • 它们如何与子命令相关? (1比1?1对多?多对多?)
  • 来电者如何选择?

我很想说execute()的来电者不应该传递这些信息;如果它知道要使用哪个命令,它应该构造一个表示该命令的对象。

如果每个名称与子命令对应1对1,则调用者可以只实例化子命令类。如果它是1对多或多对多的关系,则需要一些额外的"命令类型"班;或者你可以每次构造相同的对象,但是它应该分派给它的子命令列表。

您可能还需要一个给出命令名称的工厂方法,并构造一个适当的子命令或命令类型。这允许命令的选择是动态的,例如从用户输入,并保持任何复杂的关于在一个地方创建什么对象的逻辑。这可能是一个硬编码的switch语句,您可以在其中管理所有的名称 - 类关系,也可以是注册表,其中新的子类可以注册特定的命令名称。

最后一种情况基本上是Observer模式:命令名称是事件,子类已经注册以观察它们。作为execute(),这使得关系更加明确:如果该类实际上没有在任何地方列出,那么类的存在通常不会触发行为。在PHP中尤其如此,其中类通常仅在首次引用时在磁盘上查找,因此您在运行时实际上并不知道项目包含多少个类。