2011-03-23 74 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; 
}