偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Perl面向?qū)ο缶幊痰膬煞N實(shí)現(xiàn)和比較

開發(fā) 架構(gòu)
你對(duì)Perl面向?qū)ο蟮母拍钍欠袷煜?,本文比較了在Perl中兩種主流的Perl面向?qū)ο缶幊痰膶?shí)現(xiàn)方式,基于匿名哈希表的實(shí)現(xiàn)和基于數(shù)組的實(shí)現(xiàn)。

本文和大家重點(diǎn)討論一下Perl面向?qū)ο蟮母拍?,Perl面向?qū)ο缶幊痰膶?shí)現(xiàn)方式有兩種,分別是基于匿名哈希表的實(shí)現(xiàn)和基于數(shù)組的實(shí)現(xiàn),這里向大家簡(jiǎn)單介紹一下這兩者的區(qū)別。

Perl面向?qū)ο缶幊痰膬煞N實(shí)現(xiàn)和比較

本文比較了在Perl中兩種主流的Perl面向?qū)ο缶幊痰膶?shí)現(xiàn)方式,基于匿名哈希表的實(shí)現(xiàn)和基于數(shù)組的實(shí)現(xiàn)。深刻地剖析了兩種實(shí)現(xiàn)的技術(shù)內(nèi)幕,并且提供了可供讀者直接使用的代碼和模塊示例。在文章的最后作者比較了兩種實(shí)現(xiàn)方式的優(yōu)劣,并對(duì)讀者給出了在實(shí)際工作中選擇何種方式實(shí)現(xiàn)Perl面向?qū)ο缶幊痰慕ㄗh。

背景

我們常??梢詮能浖こ痰臅臀恼轮校蛘唔?xiàng)目經(jīng)理的口中,聽(tīng)到Perl面向?qū)ο缶幊踢@樣的字眼。與大多數(shù)時(shí)髦的技術(shù)用詞不同,Perl面向?qū)ο缶幊痰拇_可以為我們的軟件設(shè)計(jì)和開放工作帶來(lái)本質(zhì)性的變化。Perl作為一種成熟的“面向過(guò)程”的語(yǔ)言,同樣也提供了對(duì)于Perl面向?qū)ο缶幊痰闹С帧?/p>

一個(gè)好的“Perl面向?qū)ο?ldquo;的設(shè)計(jì)不僅是以數(shù)據(jù)為中心,它還盡力地封裝并且隱藏了實(shí)際的數(shù)據(jù)結(jié)構(gòu),而且只對(duì)外界開放有限的,具備良好文檔的接口。在下文中,我們將看到如何使用Perl語(yǔ)言的特性來(lái)實(shí)現(xiàn)這些Perl面向?qū)ο笤O(shè)計(jì)的優(yōu)點(diǎn)的。

Perl中有兩種不同地Perl面向?qū)ο缶幊痰膶?shí)現(xiàn),一是基于匿名哈希表的方式,每個(gè)對(duì)象實(shí)例的實(shí)質(zhì)就是一個(gè)指向匿名哈希表的引用。在這個(gè)匿名哈希表中,存儲(chǔ)來(lái)所有的實(shí)例屬性。二是基于數(shù)組的方式,在定義一個(gè)類的時(shí)候,我們將為每一個(gè)實(shí)例屬性創(chuàng)建一個(gè)數(shù)組,而每一個(gè)對(duì)象實(shí)例的實(shí)質(zhì)就是一個(gè)指向這些數(shù)組中某一行索引的引用。在這些數(shù)組中,存儲(chǔ)著所有的實(shí)例屬性。

Perl面向?qū)ο蟮母拍?/strong>

首先,我們定義幾個(gè)預(yù)備性的術(shù)語(yǔ)。
實(shí)例(instance):一個(gè)對(duì)象的實(shí)例化實(shí)現(xiàn)。
標(biāo)識(shí)(identity):每個(gè)對(duì)象的實(shí)例都需要一個(gè)可以唯一標(biāo)識(shí)這個(gè)實(shí)例的標(biāo)記。
實(shí)例屬性(instanceattribute):一個(gè)對(duì)象就是一組屬性的集合。
實(shí)例方法(instancemethod):所有存取或者更新對(duì)象某個(gè)實(shí)例一條或者多條屬性的函數(shù)的集合。
類屬性(classattribute):屬于一個(gè)類中所有對(duì)象的屬性,不會(huì)只在某個(gè)實(shí)例上發(fā)生變化。
類方法(classmethod):那些無(wú)須特定的對(duì)性實(shí)例就能夠工作的從屬于類的函數(shù)。

基于匿名散列表的方法

首先我們來(lái)談?wù)劵谀涿⒘斜淼腜erl面向?qū)ο髮?shí)現(xiàn)。首先,我們需要定一個(gè)匿名散列表,并用一個(gè)引用指向這個(gè)匿名散列表。如清單1所示,我們定義了一個(gè)初始化函數(shù)來(lái)封裝這個(gè)匿名散列表的初始化過(guò)程。這個(gè)函數(shù)接受參數(shù)作為初始值,并且用這些值初始化其內(nèi)部包含的匿名散列表,并且返回一個(gè)指向這個(gè)匿名散列表的引用。在這個(gè)例子當(dāng)中,我們創(chuàng)建了一個(gè)Person模塊,并且定義了一個(gè)可以實(shí)例化模塊Person的new函數(shù)。

清單1.基于匿名哈希表的Perl面向?qū)ο缶幊?br />  

  1. packagePerson;  
  2. subnew{  
  3. my($name,$age)=@_;  
  4. my$r_object={  
  5. “name”=>$name,  
  6. “age”=>$age  
  7. }  
  8. return$r_object;  
  9. }  
  10.  
  11. my$personA=Person->new(“Tommy”,22);  
  12. my$personB=Person->new(“Jerry”,30);  
  13. print“PersonA’sname:”.$personA->{name}.“age:”.$personA->{age}.”.\n”;  
  14. print“PersonB’sname:”.$personB->{name}.“age:”.$personB->{age}.”.\n”;  
  15.  

 但是,現(xiàn)在的這個(gè)方案有一個(gè)致命的缺點(diǎn),Perl的編譯器并不知道如何new函數(shù)所返回的指向匿名哈希表的引用屬于哪個(gè)類(模塊)。這樣的話,如果要使用類中的實(shí)例方法,只能直接標(biāo)出方法所屬于的類(模塊)的名字,并將引用作為方法的第一個(gè)參數(shù)傳遞給它,如
對(duì)于這個(gè)問(wèn)題,Perl中的bless函數(shù)提供了一個(gè)解決問(wèn)題的橋梁。bless以一個(gè)普通的指向數(shù)據(jù)結(jié)構(gòu)的引用為參數(shù),它將會(huì)把那個(gè)數(shù)據(jù)結(jié)構(gòu)(注意:此處不是引用本身)標(biāo)記為屬于某個(gè)特定的包,這樣就賦予了這個(gè)匿名哈希表的引用以多態(tài)的能力。同時(shí),我們使用箭頭記號(hào)來(lái)直接調(diào)用那些實(shí)例方法。見(jiàn)清單3。

基于匿名散列表的方法中的繼承:

Perl允許一個(gè)模塊在一個(gè)特殊的名為@ISA的數(shù)組中制定一組其他模塊的名稱。當(dāng)在模塊中找不到某個(gè)實(shí)例方法時(shí),它就為檢查那個(gè)模塊的@ISA是否被初始化。如果已經(jīng)初始化了,它就為檢查其中的某個(gè)模塊是否支持這個(gè)“缺少”的函數(shù)。如果它按照深度優(yōu)先的層次結(jié)構(gòu)搜索@ISA數(shù)組并且發(fā)現(xiàn)同名的方法,它會(huì)調(diào)用第一個(gè)被發(fā)現(xiàn)的同名方法并將控制權(quán)交給它。我們利用Perl語(yǔ)言的這個(gè)特性實(shí)現(xiàn)了繼承。

考慮這樣一個(gè)類的層次,我們定義一個(gè)Employee類,繼承于基類Person,如清單5所示。

我們將類名Person放入包Employee的ISA數(shù)組中,這樣當(dāng)調(diào)用一個(gè)在包Employee中沒(méi)有定義的函數(shù)時(shí),Perl編譯器會(huì)自動(dòng)在Person類尋找這個(gè)函數(shù)。當(dāng)用戶調(diào)用new函數(shù)初始化一個(gè)Employee對(duì)象實(shí)例的時(shí)候,Employee的new函數(shù)會(huì)在內(nèi)部調(diào)用它的基類的new函數(shù),并且返回一個(gè)包含部分以初始化的基類實(shí)例屬性的匿名哈希表。接著Employee的new函數(shù)將繼續(xù)執(zhí)行new函數(shù)的剩余代碼,完成屬于Employee自身的初始化工作,為Employee中剩余的實(shí)例屬性賦值。#p#

基于數(shù)組的方法

基于匿名哈希表的Perl面向?qū)ο缶幊谭椒ㄖ杏袃蓚€(gè)明顯的不足:一是無(wú)法為屬性提供一種訪問(wèn)限制,限制外部對(duì)內(nèi)部屬性的訪問(wèn)和改變。二是在處理大規(guī)模的實(shí)例的情況下,系統(tǒng)的內(nèi)存開銷頗大。100個(gè)實(shí)例意味著將創(chuàng)建100個(gè)散列表,這100個(gè)散列表都要為插入新紀(jì)錄的操作而分配額外的存儲(chǔ)空間。除了基于匿名散列表的實(shí)現(xiàn),我們也可以利用數(shù)組來(lái)存儲(chǔ)屬性,實(shí)現(xiàn)Perl面向?qū)ο蟮木幊獭?/p>

整個(gè)實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)非常簡(jiǎn)單,我們將為每一個(gè)類的實(shí)例屬性分配一個(gè)數(shù)組(見(jiàn)圖一,圖中的每一列對(duì)應(yīng)于類的一個(gè)實(shí)例屬性),而每一個(gè)新的實(shí)例將是跨越所有數(shù)組列的一個(gè)切片(圖中的每一個(gè)被使用的行對(duì)應(yīng)于類的一個(gè)實(shí)例)。每次需要實(shí)例化一個(gè)新的對(duì)象,new函數(shù)將被調(diào)用。一個(gè)新的邏輯行將被分配,新的實(shí)例的實(shí)例屬性將以新的行偏移量插入到相應(yīng)的屬性列當(dāng)中去。

雖然在CPAN上有許多基于這一方法的實(shí)現(xiàn),為了更加清楚地說(shuō)明如何實(shí)現(xiàn)基于數(shù)組存儲(chǔ)屬性的Perl面向?qū)ο缶幊?,我們自己?dòng)手實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的實(shí)例。我們定義了一個(gè)InsideOut類(模塊),所有的需要使用基于數(shù)組存儲(chǔ)屬性的Perl面向?qū)ο缶幊痰念惐仨毨^承這個(gè)類。InsideOut通過(guò)為每個(gè)包維護(hù)一個(gè)稱做為@_free的“空余行列表”來(lái)重用那些被定義之后又被釋放的行(空余行)。通過(guò)精心設(shè)計(jì)的數(shù)據(jù)結(jié)構(gòu),這個(gè)列表成為了一個(gè)包含所有空余行信息的鏈表,并且通過(guò)一個(gè)名為$_free的變量變量指向鏈表的頭部。表中的每個(gè)元素包含了下一個(gè)空余行的索引。當(dāng)一個(gè)對(duì)象的實(shí)例被刪除時(shí),$_free將指向這個(gè)被釋放的行,而空余列表中相應(yīng)的這個(gè)行中的元素將含有指向原有$_free所指向的前一個(gè)條目。因?yàn)楸会尫诺?ldquo;所謂”空余行和被使用的行不會(huì)重疊,所以我們可以自己的使用其中的一個(gè)屬性列來(lái)保存@_free。這是通過(guò)typelogb別名機(jī)制來(lái)實(shí)現(xiàn)的。

我們?cè)O(shè)計(jì)的InsideOut模塊為一個(gè)繼承它的類提供如下的功能:

一個(gè)名為new的構(gòu)造函數(shù),負(fù)責(zé)將為bless到繼承類中的對(duì)象分配空間。new函數(shù)將會(huì)自動(dòng)地調(diào)用initialize,而initialize可以在繼承它的類中被重載,進(jìn)行用戶自己定義的初始化工作。
我們將定義一組訪問(wèn)函數(shù),用于存取屬性。這是一組已get_attribute和set_attribute為名稱的方法,將在繼承類被自動(dòng)創(chuàng)建,包括對(duì)象自己的方法,任何人只能通過(guò)這些方法來(lái)存取對(duì)象屬性。由于InsideOut模塊是唯一知道如何存取屬性的模塊,所以用戶無(wú)法通過(guò)除此之外的任何方法來(lái)存取對(duì)象的實(shí)例屬性。
一個(gè)名為DESTROY的析構(gòu)函數(shù)。

InsideOut模塊的具體實(shí)現(xiàn)如下,見(jiàn)清單7到清單11。例七部分包含了InsideOut模塊的對(duì)外接口函數(shù)。繼承InsideOut模塊的類通過(guò)調(diào)用它提供的define_attributes函數(shù),自動(dòng)生成自己類的構(gòu)造函數(shù)和實(shí)例屬性訪問(wèn)函數(shù)。

基于數(shù)組的方法中的繼承

基于數(shù)組的方法中的繼承與基于匿名哈希表的方法中的繼承完全一樣。我們?cè)O(shè)計(jì)的InsideOut類中利用@ISA數(shù)組提供了對(duì)繼承的支持。

總結(jié)

相比于基于匿名哈希表的方法,基于數(shù)組的方法對(duì)存取屬性的訪問(wèn)提供了更好的控制和保護(hù)并且實(shí)現(xiàn)了對(duì)于對(duì)象的封裝,同時(shí)也提高了存儲(chǔ)空間的利用效率。但是基于匿名哈希表的方法也有著簡(jiǎn)單易學(xué),邏輯上較為直觀而且無(wú)需要第三方模塊支持的優(yōu)點(diǎn)。具體使用哪種方式實(shí)現(xiàn)Perl面向?qū)ο蟮脑O(shè)計(jì),還要在工作中根據(jù)實(shí)際情況進(jìn)行考慮才對(duì)。

【編輯推薦】

  1. Perl語(yǔ)言中的五大變量類型
  2. 深入解析Perl內(nèi)部函數(shù)的使用
  3. 揭秘Perl變量中Perl純變量用法
  4. 在 Perl/Tk 中使用高級(jí)窗口小部件
  5. Perl程序設(shè)計(jì)中的Perl用戶函數(shù)(子程序) 
責(zé)任編輯:佚名 來(lái)源: ibm.com
相關(guān)推薦

2010-07-13 14:54:15

Perl面向?qū)ο缶幊?/a>

2010-07-14 10:30:26

Perl多線程

2010-07-20 09:13:55

Perl面向?qū)ο缶幊?/a>

2010-07-20 13:44:02

Perl方法

2012-10-16 09:40:38

洗牌算法

2010-07-13 13:06:41

Perl面向?qū)ο?/a>

2010-07-16 17:23:57

Perl面向?qū)ο缶幊?/a>

2010-07-13 17:18:29

Perl面向?qū)ο缶幊?/a>

2010-07-20 09:33:14

Perl方法

2022-02-21 08:18:38

option編程模式

2010-07-13 14:38:33

Perl面向?qū)ο缶幊?/a>

2010-07-15 14:38:55

Perl eval函數(shù)

2010-07-20 09:23:30

Perl構(gòu)造函數(shù)

2010-07-14 16:28:58

配線架

2010-07-19 14:07:09

Perl ->符號(hào)

2009-06-19 17:05:08

MVC框架Struts和Spri

2010-07-26 15:42:34

Perl模塊

2010-02-02 14:32:32

Python線程編程

2010-11-22 13:45:43

MySQL表存儲(chǔ)結(jié)構(gòu)

2023-11-30 08:00:54

面向?qū)ο?/a>面向切面
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)