perl – 如何在Moose中处理模拟角色?

perl – 如何在Moose中处理模拟角色?,第1张

概述假设我有两个角色:Simple :: Tax和Real :: Tax.在测试情况下,我想使用Simple :: Tax,在生产中,我想使用Real :: Tax.做这个的最好方式是什么?我的第一个想法是使用不同版本的新方法来创建具有不同角色的对象: #!/usr/bin/perluse warnings;{ package Simple::Tax; use Moose::R 假设我有两个角色:Simple :: Tax和Real :: Tax.在测试情况下,我想使用Simple :: Tax,在生产中,我想使用Real :: Tax.做这个的最好方式是什么?我的第一个想法是使用不同版本的新方法来创建具有不同角色的对象:

#!/usr/bin/perluse warnings;{    package Simple::Tax;    use Moose::Role;    requires 'price';    sub calculate_tax {        my $self = shift;        return int($self->price * 0.05);    }}{    package A;    use Moose;    use Moose::Util qw( apply_all_roles );    has price => ( is => "rw",isa => 'Int' ); #price in pennIEs    sub new_with_simple_tax {        my $class = shift;        my $obj = $class->new(@_);        apply_all_roles( $obj,"Simple::Tax" );    }}my $o = A->new_with_simple_tax(price => 100);print $o->calculate_tax," cents\n";

我的第二个想法是在包的主体中使用if语句来使用不同的语句:

#!/usr/bin/perluse warnings;{    package Complex::Tax;    use Moose::Role;    requires 'price';    sub calculate_tax {        my $self = shift;        #pretend this is more complex        return int($self->price * 0.15);    }}{    package Simple::Tax;    use Moose::Role;    requires 'price';    sub calculate_tax {        my $self = shift;        return int($self->price * 0.05);    }}{    package A;    use Moose;    has price => ( is => "rw",isa => 'Int' ); #price in pennIEs    if ($ENV{TEST_A}) {        with "Simple::Tax";    } else {        with "Complex::Tax";    }}my $o = A->new(price => 100);print $o->calculate_tax," cents\n";

其中一个比另一个更好,它们中的任何一个都有一些可怕的东西,还有一种我还没想过的更好的方法.

解决方法 我的第一个建议是像MooseX :: Traits,然后在对象创建时指定不同的角色:

my $test = A->with_traits('Simple::Tax')->new(...);my $prod = A->with_traits('Complex::Tax')->new(...);

但是这打开了在没有应用角色的情况下创建A的大门.所以进一步思考,我认为你有一个X / Y问题.如果Simple :: Tax仅用于在测试环境中模拟Complex :: Tax,则可以执行多项 *** 作来覆盖Complex :: Tax实现.

例如,您可以像这样定义Simple :: Tax:

package Simple::Tax; use Moose::Role;requires 'calculate_tax';around calculate_tax => sub { int($_[1]->price * 0.05) };

然后总是使用A compose Complex :: Tax并仅在测试期间将Simple :: Tax应用于它(使用apply_all_roles).

但是,如果您在生产中需要Simple :: Tax和Complex :: Tax(而不仅仅是测试),那么最好的选择是从组合关系(确实)到委托关系(has)的重构.

package TaxCalculator::API; use Moose::Role; requires qw(calculate_tax); package SimpleTax::Calculator; use Moose; with qw(TaxCalculator::API); sub calculate_tax { ... } package ComplexTax::Calculator; use Moose; with qw(TaxCalculator::API); sub calcuate_tax { ... } package A; use Moose; has tax_calculator => (       does => 'TaxCalculator::API',handles => 'TaxCalculator::API',default => sub { ComplexTax::Calculator->new() },);

然后,如果你想覆盖它,你只需传入一个新的tax_calculator:

my $test = A->new(tax_calculator => SimpleTax::Calculator->new());my $prod = A->new(tax_calculator => ComplexTax::Calculator->new());

因为句柄会将角色中的所有方法委托为新代理,这几乎与自己编写角色相同.

总结

以上是内存溢出为你收集整理的perl – 如何在Moose中处理模拟角色?全部内容,希望文章能够帮你解决perl – 如何在Moose中处理模拟角色?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1239388.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存