如何创建一个对象,其创建属性隐式指定派生类?

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)

Nic*_*son 5

也许你可以用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)

班级:工厂也可以,但可能有点超出您的需求.