2011-03-23 49 views
1

编写子函数并将其全部放入一个文件与编写软件包有什么区别?在涉及Perl时,面向对象比过程更好吗?Perl设计问题

基本上寻找OO比程序更好的场景的例子。

谢谢!

回答

5

首先,为了澄清一下,程序和OO之间的区别与将所有代码放入一个文件与将其放入单独模块之间的区别不同。您可以拥有独立的模块,这些模块包含您可以通过程序调用的功能。

使用模块,OO或程序的地方是有利的,如果代码将被重用或者它只是一个庞大的代码库。如果你有一个包含10个不同CGI脚本的CMS,它们都可以做几件相同的事情,比如验证一个用户会话,那么把这些代码放到一个单独的模块中,而不是在每个CGI中重写它都是有意义的。如果它是特定于该脚本的20行函数,则将其保留在同一个文件中。

是否使用OO或程序取决于你在做什么。这些天大部分时间大多数人会对OO青睐。我同意他们,因为我觉得它可以帮助你从逻辑上考虑你的代码,并以一种理智的方式将它们组合在一起,以后很容易管理和更新。

0

我喜欢将尽可能多的代码放入模块中。关于模块的好处是,您可以使用Perl的测试工具(证明和测试::更多)来轻松编写和管理单元测试。所以如果几乎所有的代码都在模块中,几乎所有代码都是可测试的。当我编写脚本时,我喜欢用一个简单的包装器来解析我的脚本中的配置和命令行选项(可能使用诸如Config :: Any或Getopt :: Long之类的模块)。该脚本还包含usage子例程。然后我添加一个main子程序。 main很简单:

sub main { 
    my $cfg = shift; 

    my @collected_data; 

    for my $file (@{ $cfg->{files}) { 
     eval { 
      my $fh = get_handle_from_file($file); 

      my $xyz_data = parse_xyz_data($fh); 

      push @collected_data, extract_data($xyz_data, $cfg->{filter}); 

      1; 
     } or do { 
      my $e = [email protected]; 
      $e = "an unknown error occurred" unless defined $e; 

      warn "Error parsing '$file': $e\n"; 
     };   
    } 

    my %summary_data = summarize_data(@collected_data); 

    write_summary($cfg->{summary_target}); 

    return; 
} 

几乎所有的配套子程序将生活在一个或多个模块。

OOP是关联数据和行为的好方法。这可以使代码更具可读性并减少混乱。

$foo->eat_something($sandwich) 

更容易理解比:

eat_something($sandwich, $likes_salty, $likes_sour, $likes_sweet, $likes_spicy); 

所有多余的废物都被派上用场$foo对象属性捆绑起来,不会搞乱子调用一起旅行。

当然,你可以这样做:

eat_something($foo, $sandwich) 

其中$ foo是口味偏好的只是一个普通的哈希值。无论如何,这基本上就是Perl OO所做的。调用者(对象或类名称)作为第一个参数传递给每个方法。您确实会失去方便的命名空间,继承和动态方法调用。在这三项费用中,方便的名字空间将最容易被忽略。海事组织,继承被高估,应该只使用很少。动态方法调用可以派上用场,因为调度表很方便。

在OO Perl中,你无法在过程式Perl中完成任何事。但是,OO使某些事情非常方便。

最后,让我在OO风格重写我的神话脚本(我会做得太过火了一下就OO,只是为了演示):

子主{ 我的$ CFG =移位;

my $cd = Data::Collection->new(); 

    for my $file ($cfg->files) { 
     eval { 

      # skip the step of creating a handle first. The parsing object 
      # can take a file and get a handle or could be passed a handle.    

      my $xyz_parser = File::XYZ::Parse->new(file => $file); 

      # The parser returns an XYZ::Data object 

      my $xyz_data = $xyz_parser->parse; 

      $cd->add_data($xyz_data->extract_data($cfg->filter); 

      1; 
     } or do { 
      my $e = [email protected]; 
      $e = "an unknown error occurred" unless defined $e; 

      warn "Error parsing '$file': $e\n"; 
     };   
    } 

    # Skip the step of separate summarization, since the cd object can check if 
    # the summary has been done, and if not generate and cache it as needed. 

    $cd->write_summary($cfg->summary_target); 

    return; 
}