以下のパターンを探しています。(私は Perl で作業していますが、言語は特に問題ではないと思います)。
親クラスが Foo で、子クラスが Bar、Baz、Bazza です。
Foo を構築する方法の 1 つは、文字列を解析することです。その文字列の一部は、作成するクラスを暗黙的に指定します。たとえば、「http:」で始まる場合はバーですが、そうではなく「[Date]」が含まれている場合、Baz はそれを好みます。
ここで、Foo がそのすべての子について知っていて、どの文字列が Bar で、何が Baz であるかなどを知っている場合、適切なコンストラクターを呼び出すことができます。ただし、基本クラスはその子に関する知識を持ってはいけません。
私が望むのは、Foo のコンストラクターがその子を順番に試すことができるようにすることです。そのうちの 1 つが「はい、これは私のものです。私が作成します」と言うまでです。
文字列を受け入れる子が複数存在する可能性があるため、一般的なケースでは、この問題は明確に定義されていないことを認識しています。したがって、それらが呼び出される順序が重要です。これを無視して、文字列の特性が1 つの子クラスだけがその文字列を好むようなものです。
私が思いついた最善の方法は、子クラスが初期化時に基本クラスに「登録」して、コンストラクターのリストを取得し、それらをループすることです。しかし、私が見逃しているより良い方法はありますか?
サンプルコード:
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;
}