【问题标题】:Perl Moose class designPerl Moose 类设计
【发布时间】:2011-12-03 16:17:25
【问题描述】:

我有一个基于 Moose 的课程 (Foo),它有 4 个属性,可以说:

SF1...SF4

HashRef[Any] 类型的每个。

目前都有默认值。稍后,我们将从 MySQL 表中获取这些值。

我的方法是,让Foo 类根据数据的来源使用角色,我可以将SF1...SF4 存储在一个名为Foo::DB 的角色中,它将为SF1...SF3 提供默认值来自数据库。

还有一个角色,Foo::Local,它将具有硬编码的默认值,所以以后,当我们使用数据库时,我只需要更改'with....'。

我是朝着正确的方向前进,还是应该采取不同的方式?

【问题讨论】:

  • 短语“...一个名为 Foo::DB 的角色 [...] 将提供 [...] 数据库中的默认值。] 引发了一个危险信号。默认值来自数据库?这可能只是措辞问题。但无论如何,与大多数其他问题一样,这取决于您使用这种方法的原因。如果用于原型制作或测试,该方法是显而易见的,但如果您想要一些生产代码可以切换数据源,也许不那么紧密的绑定更好。

标签: perl oop roles moose


【解决方案1】:

不清楚为什么需要从角色填充数据。我认为您可以只使用初始化程序潜艇。让你的属性变得懒惰,然后定义 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

如果你告诉我为什么你这样做,那么我可以给你一个更好的答案。

【讨论】:

    【解决方案2】:

    让我看看我是否理解正确。

    你有四个属性应该被分配一个默认值。

    您已在 MySQL 数据库模式中定义了该默认值。您希望发生的是,无论何时创建 Foo 实例,默认值都将从您在 MySQL 模式中定义的默认值中填充。

    如果我对您尝试做的事情的理解是正确的,那么我的建议是:不要那样做(除非这绝对是您项目的要求)。使用 Moose 的默认或构建器属性定义属性的默认值。

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

    如果您要查找已在数据库架构中设置的默认值,而不是在您的类中定义它们,您将为自己创建更多工作,给您的程序增加不必要的复杂性,并且会增加昂贵的数据库调用,这可能避免。您需要解析数据库模式并确定给定属性的默认值。每次创建新对象(昂贵)时都需要执行此操作,或者创建默认值的缓存。当然你可以创建一个 Moose 扩展来实现一些魔法并且透明地为你做这件事。对于一个不那么吸引人的解决方案,似乎需要做很多工作。我只会使用 Moose 的“默认”属性,除非你有一个真的很好的理由不这样做。

    【讨论】:

    • 另外,您可能对使用 ORM(对象关系映射)框架感兴趣,也可能不感兴趣。我编写了一个名为 Storm 的模块,用于处理 Moose 对象到 SQL 数据库的存储和检索。它对许多对象关系映射框架采用不同的方法——您不需要提供模式或花费大量时间来设计数据库。创建类,确保应用了 Storm::Role::Object 角色。 Storm 然后可以为您设置和管理您的数据库表。 Storm 仍处于测试阶段,但正在生产代码中使用。其他值得注意的 ORM 是 Fey::ORM 和 KiokuDB。
    猜你喜欢
    • 1970-01-01
    • 2011-07-09
    • 2014-05-23
    • 2022-01-14
    • 2012-12-06
    • 2013-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多