Col*_*ine 3 perl inheritance constructor design-patterns creation
我正在寻找以下模式.(我在Perl工作,但我不认为语言特别重要).
父母班Foo,儿童Bar,Baz,Bazza.
构造Foo的方法之一是解析字符串,该字符串的一部分将隐式指定要创建的类.因此,例如,如果它开始'http:'那么它是一个Bar,但如果它没有,但它包含'[Date]',那么Baz喜欢它,依此类推.
现在,如果Foo知道它的所有子节点,以及什么字符串是Bar,什么是Baz等,它可以调用适当的构造函数.但基类不应该对其子女有任何了解.
我想要的是Foo的构造函数能够依次尝试它的孩子,直到其中一个人说"是的,这是我的,我会创造的东西".
我意识到在一般情况下这个问题没有明确定义,因为可能有多个子接受字符串,因此调用它们的顺序很重要:忽略它并假设字符串的特征这样只有一个子类会喜欢这个字符串.
我提出的最好的方法是让子类在初始化时"注册"基类,以便获取构造函数列表,然后循环它们.但是,我有一个更好的方法吗?
示例代码:
package Foo;
my @children;
sub _registerChild
{
push @children, shift();
}
sub newFromString
{
my $string = shift;
foreach (@children) {
my $object = $_->newFromString(@_) and return $object;
}
return undef;
}
package Bar;
our @ISA = ('Foo');
Foo::_registerChild(__PACKAGE__);
sub newFromString
{
my $string = shift;
if ($string =~ /^http:/i) {
return bless(...);
}
return undef;
}
Run Code Online (Sandbox Code Playgroud)
也许你可以用Module :: Pluggable来实现它?这样就无需注册.
我之前采用的方法是使用Module :: Pluggable加载我的子模块(这允许我通过简单地编写和安装它们来添加新的子模块).每个子类都有一个构造函数,它返回一个受祝福的对象或undef.你遍历你的插件,直到你得到一个对象,然后返回它.
就像是:
package MyClass;
use Module::Pluggable;
sub new
{
my ($class, @args) = @_;
for my $plugin ($class->plugins)
{
my $object = $plugin->new(@args);
return $object if $object;
}
}
Run Code Online (Sandbox Code Playgroud)
有班级:工厂也可以,但可能有点超出您的需求.