1

我有一组与数据库交互的 Moose 角色(很快就会变大)。它们具有 create_foo_record、update_foo_record、delete_foo_record 等方法。(它们不是数据库访问的简单包装器,因为它们执行诸如转换和规范化数据、记录操作等操作。在某些情况下,它们也可以创建和更新相关记录.)

这段代码非常通用,所以我想要一个实现这些方法的基本模块,而不是有两个模块的剪切和粘贴代码,使用配置参数告诉他们哪些表、列、规范化函数等。

我的直觉是写一些“高阶”的东西来生成这些函数,但我认为用 Moose 的方式来做更合适。(不过,我是 Moose 新手……)

天真的方法是让基类成为一个角色,它的方法采用配置参数,但这看起来很混乱。

理想情况下,我希望基类具有使用它的角色设置的私有配置,例如

__PACKAGE__->config( foo => 'bar' );

但我不确定如何使用 Moose 来做到这一点。我的尝试遇到了错误,抱怨将类扩展为角色。或者配置参数被证明不是私有的,并且会干扰其他角色或被使用角色的 Catalyst 控制器中的相应配置干扰。

如果可以在基类中使用“Catalyst::Component”,但以某种方式将其扩展到角色,那将是理想的。但我不知道该怎么做,或者即使有可能。

谢谢。

4

2 回答 2

2

撇开这听起来很像DBIx::Class::SchemaLoader 不说,如果我理解正确的话,你想要......

  • 存储系统配置信息的东西。
  • 它有默认值。
  • 这些默认值可以在每个类的基础上被覆盖。

一种方法是创建一个角色并利用构建器方法。角色通过构建器方法定义默认值,并且每个类都可以覆盖。

use v5.10;

{
  package MyConfig;

  use Moose::Role;

  has user => (
      is      => 'ro',
      lazy    => 1,
      builder => '_build_user',
  );

  sub _build_user {
    return "default_user";
  }
}

{
  package MyApp;
  use Moose;

  with 'MyConfig';

  sub _build_user {
    return "some_user";
  }
}

{
  package DefaultApp;
  use Moose;

  with 'MyConfig';
}

say MyApp->new->user;        # some_user
say DefaultApp->new->user;   # default_user

另一种是利用属性继承

use v5.10;

{
  package MyConfig;

  use Moose::Role;

  has user =>
      is      => 'ro',
      lazy    => 1,
      default => "default_user",
  ;
}

{
  package MyApp;
  use Moose;

  with 'MyConfig';

  has '+user' =>
      default => 'some_user'
  ;
}

{
  package DefaultApp;
  use Moose;

  with 'MyConfig';
}

say MyApp->new->user;        # some_user
say DefaultApp->new->user;   # default_user

它们基本上是一样的。前者以更传统的 OO 风格完成,更机械化。后者是使用一点 Moose 魔法完成的,并且更具声明性和紧凑性。各有优缺点,适合您的使用。

于 2012-12-22T03:41:19.797 回答
1

我认为我需要的是参数化角色http://metacpan.org/pod/MooseX::Role::Parameterized

于 2012-12-22T17:13:40.803 回答