Perl Moose дизайн класса - PullRequest
       23

Perl Moose дизайн класса

3 голосов
/ 03 декабря 2011

У меня есть класс (Foo), основанный на Moose, который имеет 4 свойства, скажем:

SF1...SF4

каждого типа HashRef[Any].

В настоящее время все по умолчанию имеютценности.Позже мы собираемся получить эти значения из таблицы MySQL.

Мой подход состоял в том, чтобы класс Foo потреблял роли в зависимости от того, откуда поступают данные, я могу хранить SF1...SF4 вроль с именем Foo::DB, которая будет предоставлять SF1...SF3 значения по умолчанию из базы данных.

А также иметь роль Foo::Local, которая будет иметь жестко заданные значения по умолчанию, поэтому позже, когда мы будем использовать DB, мне нужно будет только поменять 'с ....'.

Я иду в правильном направлении, или я должен сделать это по-другому?

Ответы [ 2 ]

1 голос
/ 14 июня 2012

Непонятно, зачем вам нужно заполнять данные из роли. Я думаю, что вы можете просто использовать подпрограммы инициализатора. Сделайте ваши атрибуты ленивыми, а затем определите init_attribute subs. Когда значение атрибута требуется в первый раз, если оно еще не установлено, будет вызываться sub инициализатора для предоставления значения. Когда вы подключаете базу данных, вы можете просто научить своих инициализаторов, как запрашивать в базе данных значения.

package Foo;
has SF1 => ( is => 'rw', lazy => 1, isa => 'HashRef[Any]' );

sub init_SF1 {
    { hi => 'how are you' }
};

В качестве альтернативы, если вы хотите иметь возможность переходить назад и вперед (например, для тестирования), тогда да, вы можете связать ваши инициализаторы в роли и применять роль в зависимости от ситуации. Или вы можете просто указать значения, встроенные в ваши тесты. Например

use Test::More;
use Foo;
my $foo = Foo->new(
    SF1 => { 
        row1 => 'fake test data', 
        row2 => 'also fake' 
    },
    SF2 => {},
); # now init_SF[12] will not be called

Если вы скажете мне почему вы делаете это, тогда я могу дать вам лучший ответ.

0 голосов
/ 12 января 2013

Дайте мне посмотреть, правильно ли я вас понимаю.

У вас есть четыре атрибута, которым должно быть присвоено значение по умолчанию.

Вы определили это значение по умолчанию в схеме базы данных MySQL. Вы хотели бы, чтобы при каждом создании экземпляра Foo значения по умолчанию заполнялись значениями по умолчанию, определенными вами в схеме MySQL.

Если я правильно понимаю, что вы пытаетесь сделать, то мой совет: Не делайте так (если это не является обязательным требованием для вашего проекта). Определите значения по умолчанию для ваших атрибутов, используя свойства Moose по умолчанию или свойства компоновщика.

has 'bar' => (
    default => 'fubar',
);

Если вам нужно искать значения по умолчанию, которые были установлены в схеме базы данных, а не определять их в вашем классе, вы создадите больше работы для себя, добавите ненужную сложность в свою программу и добавите дорогие вызовы базы данных, которые могли бы избегать. Вам нужно будет проанализировать схему базы данных и определить, какие значения по умолчанию должны быть для данного атрибута. Вам нужно будет делать это каждый раз, когда вы создаете новый объект (дорогой), или создавать кэш значений по умолчанию. Конечно, вы можете создать расширение Moose, которое реализует некоторую магию и делает это для вас прозрачно. Похоже, много работы для не очень привлекательного решения. Я бы просто использовал свойство атрибута по умолчанию Moose, если у вас нет действительно веских причин не делать этого.

...