我正在尝试编写一个 Moose 类,该类解析带有标题的格式略有不同的 csv 文件,并返回代表文件中数据的对象列表。这是代码的简化版本:
package MyParser;
use Moose;
use namespace::autoclean;
use Text::CSV_XS;
use MyData; #class that represents data for each row of csv
has 'type' => ( is => 'ro', isa => 'Str', required => 1 );
sub get_data {
my($self, $file) = @_;
open my $fh, '<', $file || die "Can't open file $!";
my $csv = Text::CSV_XS->new;
$csv->column_names($csv->getline($fh));
my @data;
if ($self->type eq 'filetype1'){
while (my $row = $csv->getline_hr($fh)){
push @data, MyData->new(field1 => $row->{col1},
field2 => $row->{col2},
field3 => $row->{col3},
);
}
}
elsif ($self->type eq 'filetype2'){
while (my $row = $csv->getline_hr($fh)){
push @data, MyData->new(field1 => $row->{colA},
field3 => _someFunction($row->{colB}), # _someFunction does some manipulation with the data
field5 => $row->{colC},
);
}
}
elsif ($self->type eq 'filetype3'){
while (my $row = $csv->getline_hr($fh)){
push @data, MyData->new(field1 => $row->{column_1},
field2 => _someOtherFunction($row->{column_2}), # _someOtherFunction does some manipulation with the data
field3 => $row->{column_3},
field4 => $row->{column_4},
field5 => $row->{column_5},
);
}
}
close $fh;
return \@data;
}
__PACKAGE__->meta->make_immutable;
1;
MyData 类只是一个简单的数据结构,其中一些属性具有默认属性(因此与上面不同的初始化)。某些 csv 文件类型还具有需要一些操作的列(例如,需要进入简单公式的数字),这些列取决于文件类型。然后将此 MyData 返回到我的主脚本以插入到 oracle 中的表中。
我的目标是让 MyParser 处理某些指定类型的 csv 文件,如果需要,这些文件可以扩展,并从 get_data 方法返回 MyData 列表。但是,现在的方法似乎不是我要解决的问题的优雅/简单的解决方案。
所以我想问/评论的是:
有没有更好/更简单的方法来解决这个问题(可能通过工厂模式等设计模式)?
还是我想解决一些看起来很简单的事情,让事情变得非常复杂?