是否有更简单或更好(=>更易于维护)的方法来使用 Perl 和 Moose
根据传入数据实例化类?
以下代码是我正在处理的一个项目的精简示例。
package FooBar;
use Moose;
has 'SUBCLASS' =>('isa'=>'Str',required=>'1',is=>'ro');
has 'MSG' =>('isa'=>'Str',required=>'1',is=>'ro');
sub BUILD {
my $self = shift;
my ($a)=@_;
bless($self,$a->{SUBCLASS})
}
sub Hi {
my $self=shift;
print "Hi, I'm a " . ref($self) ." and I say [". $self->MSG()."]\n";
}
package Foo;
use Moose;
extends ("FooBar");
package Bar;
use Moose;
extends ("FooBar");
package main;
use strict;
use warnings;
for my $line (<DATA>) {
my ($case,$msg)=split(/[\n\r,]\s*/,$line);
FooBar->new(SUBCLASS=>$case,MSG=>$msg)->Hi();
}
__DATA__
Foo, First Case
Bar, Second Case
EDIT :让我震惊的是,这几乎是您调用 DBI 时发生的情况。根据您传递的参数,它将使用完全不同的代码,同时保持(大部分)一致的接口(interface)
最佳答案
哎呀。 Stevan 有一个非常有说服力的论点,即 new
应该始终只有
返回一个类的实例。其他任何东西都会让新人学习感到困惑
系统。
你可能想看看
MooseX::AbstractFactory。
如果这对你不起作用,那么:
package FooBar;
use Moose;
has [qw(SUBCLASS MSG)] => ( is => 'ro', required => 1);
sub create_instance {
return $self->package->new(message => $self->msg);
}
package FooBar::Object;
use Moose;
has msg => ( is => 'ro', required => 1);
sub Hi {
my $self = shift;
print "Hi, I'm a " . ref($self) ." and I say [". $self->MSG()."]\n";
}
package Foo;
use Moose;
extends qw(FooBar::Object);
package Bar;
use Moose;
extends qw(FooBar::Object);
package main;
or my $line (<DATA>) {
my ($case,$msg)=split(/[\n\r,]\s*/,$line);
FooBar->new(SUBCLASS=>$case,MSG=>$msg)->create_instance->Hi
}
__DATA__
Foo, First Case
Bar, Second Case
当然,还有许多其他方法可以在 Moose 中实现相同的概念。在不知道域问题的具体情况的情况下,很难说像 MooseX::Traits 这样的东西不会更好:
package Foo;
use Moose;
with qw(MooseX::Traits);
package Bar;
use Moose;
with qw(MooseX::Traits);
package Messaging;
use Moose::Role;
has msg => ( is => 'ro', required => 1);
sub Hi {
my $self = shift;
print "Hi, I'm a " . ref($self) ." and I say [". $self->MSG()."]\n";
}
package main;
use strict;
Foo->with_traits('Messaging')->new( msg => 'First Case')->Hi;
这大致是另一张海报关于使用基于角色的解决方案的意思。
关于perl - 如何在 Perl 和 Moose 中编写工厂代码?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1244228/