我正在尋找以下模式。 (我正在使用Perl,但我認爲語言並不重要)。如何創建派生類由創建屬性隱式指定的對象?
與父母班Foo,和兒童酒吧,巴茲,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;
}
謝謝。邏輯模塊:: Pluggable非常好,正是我所期待的;但它可能不適合我們的情況,因爲它可能不會出現在我們用戶的機器上,所以我們必須使用我們自己的模塊進行分發。 與我的註冊解決方案相比,這也是「神奇的」,所以它可能不太清楚。 但是,感謝您的關注。 – 2009-06-16 14:27:48
這是有點神奇,但默認行爲只會加載MyClass :: Plugin命名空間中的類(並且該命名空間很容易覆蓋)。因此,註冊與在該名稱空間中創建模塊的效果完全相同。 很顯然,它是一個CPAN模塊,但如果您現在可以在沒有CPAN(或大量的車輪重新創建)的情況下管理Perl中的任何嚴重應用程序,我會感到驚訝。 – 2009-06-16 15:06:05