Как я могу создать объект, чей производный класс указан неявно свойствами создания?

Ответов: 4


5 принят

Возможно, вы могли бы реализовать это с помощью модуля :: 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;
    }
}

Там есть класс: фабрика, но это может быть чуть-чуть сверху для ваших нужд.


1

Кажется, вы пытаетесь создать один класс как базового класса, так и фабрики. Не. Используйте 2 отдельных класса. Что-то вроде этого:

package Foo;

package Bar;
use base 'Foo';

package Baz;
use base 'Foo';

package Bazza;
use base 'Foo';

package Factory;
use Bar;
use Baz;
use Bazza;

sub get_foo {
    my ($class, $string) = @_;
    return Bar->try($string) || Baz->try($string) || Bazza->try($string);
}

И затем используйте его как:

my $foo = Factory->get_foo($string);

Таким образом, ваш базовый класс не должен знать о ваших дочерних классах, только ваш завод. А дочерние классы также не должны знать друг о друге, только Factory должен знать детали, какие дочерние классы попробовать и в каком порядке.


0

Вы можете реализовать произвольный алгоритм поиска в классе Foo, который ищет существующие дочерние классы. Возможно, на основе файлов конфигурации, снабженных дочерними классами, или с помощью любого другого механизма, о котором вы могли бы подумать.

Затем класс Foo обнаружит существующие клиентские классы во время выполнения и вызовет их по очереди.

Кроме того, вы можете кэшировать результаты поиска и приблизиться к решению реестра, которое вы уже описали сами.


0

Если вы примете свой комментарий о родительском классе, который не содержит информацию о чилидрене и ваш метод делегирования задачи по определению пригодности дочерних классов к самому классу, то, вероятно, правильно отдать выбор класса из родительского класса и создать singleton для этой задачи.

по крайней мере, это было бы моим предпочтением ... из этого ваш текущий родительский класс (который предположительно имеет некоторые общие функции в ваших дочерних классах), по-видимому, может стать либо абстрактным, либо интерфейсом.

тогда синглтон мог бы управлять построением всех дочерних классов и их распределением (клонировать их, если они не являются функциональными?) ... кроме того, дочерние классы могут быть перемещены в отдельную dll для содействия разделению.

извините, что это не прямое решение. Я делал это в прошлом, управляя списком классов в синглете, как вы здесь. идея синглтона заключается в том, что если вы хотите использовать какое-либо дорогое отражение, вам нужно сделать это только один раз.

Perl, наследование, конструктор, дизайн-шаблоны, создание,
Похожие вопросы
Яндекс.Метрика