Я ищу образец для следующего. (Я работаю на Perl, но не думаю, что язык имеет особое значение).
С родительским классом Foo и дочерними Bar, Baz, Bazza.
Одним из методов создания Foo является разбор строки, и часть этой строки будет неявно указывать, какой класс должен быть создан. Так, например, если он начинается с «http:», то это Bar, но если это не так, но содержит «[Date]», тогда это нравится Базу и так далее.
Теперь, если 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;
}