我很确定我的问题已在某个地方得到解答,但似乎我找不到答案,所以我试试。
子类是否有办法监听其父类的静态方法并执行其静态方法之一?或者它应该使用接口,如果是这样,你会怎么做?
最好的例子是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方法,但我希望可以有更优雅的东西来实现它。
答案 0 :(得分:1)
实际上,我认为您当前的方法是优雅的(看Command设计模式)。
据我了解,您要实现的是执行Command
的所有已注册子类的方法。至少两点 不优雅。 首先,您必须从所有声明的类中过滤掉您的子类(使用get_declared_classes
)。这可能非常详尽。 其次,在这种情况下,您只能通过添加或删除类来控制要执行的命令数。这实际上违背了OOP(对象 - 面向编程,而非面向类编程)的目的。程序的流程应该由对象的交互来定义。
答案 1 :(得分:0)
$name
的{{1}}参数感觉需要在此检查:
我很想说execute()
的来电者不应该传递这些信息;如果它知道要使用哪个命令,它应该构造一个表示该命令的对象。
如果每个名称与子命令对应1对1,则调用者可以只实例化子命令类。如果它是1对多或多对多的关系,则需要一些额外的"命令类型"班;或者你可以每次构造相同的对象,但是它应该分派给它的子命令列表。
您可能还需要一个给出命令名称的工厂方法,并构造一个适当的子命令或命令类型。这允许命令的选择是动态的,例如从用户输入,并保持任何复杂的关于在一个地方创建什么对象的逻辑。这可能是一个硬编码的switch语句,您可以在其中管理所有的名称 - 类关系,也可以是注册表,其中新的子类可以注册特定的命令名称。
最后一种情况基本上是Observer模式:命令名称是事件,子类已经注册以观察它们。作为execute()
,这使得关系更加明确:如果该类实际上没有在任何地方列出,那么类的存在通常不会触发行为。在PHP中尤其如此,其中类通常仅在首次引用时在磁盘上查找,因此您在运行时实际上并不知道项目包含多少个类。