我正在扩展一个模块,我想了解一些有关良好实践的提示。特别命名空间冲突:他们究竟是什么以及如何避免它们。我应该如何访问Perl子类中的实例数据?
扩展时,我不应该访问SUPER类中的变量,只能通过访问器或对象方法更改其状态?如果没有(或有限)访问者,该怎么办?我“允许”直接访问这些对象变量吗?
干杯!
我正在扩展一个模块,我想了解一些有关良好实践的提示。特别命名空间冲突:他们究竟是什么以及如何避免它们。我应该如何访问Perl子类中的实例数据?
扩展时,我不应该访问SUPER类中的变量,只能通过访问器或对象方法更改其状态?如果没有(或有限)访问者,该怎么办?我“允许”直接访问这些对象变量吗?
干杯!
最好只通过访问者访问事物,因为这可以防止超类实现中的变化影响子类。你应该远离任何以底线开始的东西。这些东西对班上是私人的。尽量远离任何没有记录的东西。依靠这些东西会让你陷入麻烦。另外,考虑使用has-a与is-a的关系。
让我们来想象一个小部件类。这个类有名称和价格的成员(注意,这一切都不是特别好代码,我刚才扔的版本出来思考了一个例子的缘故):
package Widget;
use strict;
use warnings;
sub new {
my $class = shift;
my %args = @_;
return bless {
price => $args{price} || 0,
name => $args{name} || "unkown",
}, $class;
}
sub price { shift->{price} }
sub name { shift->{name} }
1;
你决定子类控件加配重块:
package Widget::WithWeight;
use strict;
use warnings;
use base 'Widget';
sub new {
my $class = shift;
my %args = @_;
my $self = $class->SUPER::new(%args);
$self->{weight} = $args{weight} || 0;
return bless $self, $class;
}
sub weight { shift->{weight} }
sub price_per_pound {
my $self = shift;
return $self->{price}/$self->{weight};
}
1;
现在想象一下,第一个模块的作者改变他/她对如何存储的价格头脑。或许正是存储为一个浮点数和作者意识到,把它作为便士的整数会更好:
package Widget;
use strict;
use warnings;
sub new {
my $class = shift;
my %args = @_;
if ($args{price}) {
$args{price} =~ s/[.]//;
}
return bless {
price => $args{price} || "000",
name => $args{name} || "unkown",
}, $class;
}
sub price {
my $self = shift;
my $price = $self->{price};
substr($price, -2, 0) = ".";
return $price;
}
sub name { shift->{name} }
1;
突然,你的测试将启动失败,但如果你已经使用了price
访问,而不是,你会被这种改变所隔离。
如果您从两个模块继承为一个模块并且它们都提供(导出)相同的子项,则可能发生名称空间冲突。
我建议你看看Moose,它是Perl的一个扩展,它为你提供了类和角色。如果您使用角色,则可以避免许多冲突。请参见http://www.iinteractive.com/moose/
Moose还为类变量生成自动访问器,使得从继承类访问它们更安全。
我没有使用_foobar方法,但是,我直接访问一些变量的内部表示,例如: 现实生活中的值存储为散列裁判是这样的: $自= { “财产” = > {objnum => NUM,type => TYPE,value => VALUE}, } 我应该*不*直接通过$ self访问'property',如$ self - > {property}?我应该只访问它,如果它有一个get_property()访问器? 在我的安装脚本中'需要'SUPER类模块的一个特定版本是一个白痴的事情吗? – 2009-08-04 14:01:20
如果它们没有存储在带有下划线的散列(例如`$ self - > {_ property}`)中,那么它们是公平的游戏,但是访问方法是更安全的方法(保护您免受实施更改)。 – 2009-08-04 14:10:36