国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

VB.Net中文教程(11) Prototype樣式

2024-07-10 13:05:30
字體:
來源:轉載
供稿:網友


主題: prototype樣式
副題: 多形性、接口(interface)


????????? 內容 ?????????
v 1. 樣式
v 2. 對象之原型(object prototype)
v 3. 以vb落實prototype樣式
v 4. prototype樣式之應用----- 組件之設計與組裝


1. 樣式
erich gamma 等人的名著──"design patterns: elements of reusable object-oriented software" 含有23個重要的設計樣式(design pattern)。顧名思義﹐「樣式」就是大家可「有樣學樣﹐依樣畫葫蘆」﹐并一而再、再而三地在不同場合﹐重復使用(reuse) 它來解決常見之問題。
樣式必須常常使用﹐且愈純熟愈好﹐才能隨外界環境(context) 而加以變化﹐才能確實解決問題(problem) 。像孫子兵法、太極拳法皆含有許多樣式(或稱為招式)﹐必須心領神會﹐并實際練習之﹐才能達到爐火純青之地步。其主要原因是﹕單一樣式(招式)常只解決個小問題﹐而大問題可能需要多種樣式混合使用才行。如何將小樣式組合成為大樣式來解決大問題呢﹖這常需一套完整的法則(rule)﹐通稱為「樣式語言」(pattern language)。本文引用gamma書中的prototype樣式﹐說明如何以vb的接口來實作之,也讓您更能善用多形性觀念。以下就請您仔細看如何使用prototype 樣式了。


圖1、prototype樣式的uml圖


2. 對象之原型 (object prototype)
人們日常生活中﹐常見下述說法﹕

「我要養一只像加菲貓一樣的貓」
「我將來要娶個美如西施的妻子」
......

其中﹐加菲貓和西施皆是prototype (或譯為范例)。當您說上述兩句話時﹐聽者立即能經由prototype 對象(即加菲貓或西施)來了解您心中所欲描述之新對象。在軟件方面﹐使用者可藉prototype 來告訴計算機﹕

「我要的對象就像這個prototype 對象」

于是﹐計算機依該prototype 對象來造出一模一樣的新對象給使用者。
回想﹐我們所熟悉的vb、c#、java或c++語言中﹐皆是借著「類別」來描述對象之特性﹐然后計算機則依類別之描述來造出新對象。這種就通稱為class-based programming ﹔而前者稱為prototype-based programming 。
隨著﹐軟件零組件(sofrware ic) 觀念的流行﹐prototype-based programming 觀念也愈來愈重要了。既使像vb語言﹐也能支持prototype-based programming 。


3. 以vb落實prototype樣式
上圖1是gamma書中所列出的prototype樣式。下圖2則是個實際的例子。


圖2、繪圖對象的prototype

對象設計者從shape衍生出circle及rectangle兩類別,并各誕生1個prototype對象,且存入shapelist串行或數組之中。設計者必須為各類別定義clone( )函式來誕生新對象,并構成多形性。于是對象裝配者只需呼叫clone( )函數就能獲得新對象,而不必具有類別觀念。未來,設計者可從shape類別衍生出許許多多子類別,并把對象放入shapelist中,供裝配者使用。
茲看看如何以vb來落實上圖2的uml模式:

'ex01.bas
imports system.componentmodel
imports system.drawing
imports system.winforms
'-------------------------------------------------------------------------
class shape
protected lx, ly as integer
public sub setxy(byval x as integer, byval y as integer)
lx = x
ly = y
end sub
public overridable sub draw()
end sub
public overridable function clone() as shape
end function
end class

class circle
inherits shape

public overrides sub draw()
messagebox.show("drawing a circle at (" + str(lx) + ", " + str(ly) + ")")
end sub
public overrides function clone() as shape
clone = new circle()
end function
end class

class rectangle
inherits shape

public overrides sub draw()
messagebox.show("drawing a rectangle at (" + str(lx) + ", " + str(ly) + ")")
end sub
public overrides function clone() as shape
clone = new rectangle()
end function
end class
'-------------------------------------------------------------------------------------
class shapelist
private tlist(10) as shape
private counter as integer

public sub new()
counter = 0
end sub
public sub addshape(byval sobj as shape)
tlist(counter) = sobj
counter = counter + 1
end sub
public function getshape(byval i as integer) as shape
getshape = tlist(i)
end function
public sub draw()
dim i as integer
for i = 0 to counter - 1
tlist(i).draw()
next
end sub
end class
'-------------------------------------------------------------------------------------
public class form1
inherits system.winforms.form
public sub new()
mybase.new()
form1 = me
'this call is required by the win form designer.
initializecomponent()
'todo: add any initialization after the initializecomponent() call
end sub
'form overrides dispose to clean up the component list.
public overrides sub dispose()
mybase.dispose()
components.dispose()
end sub
#region " windows form designer generated code "
......
#end region
protected sub form1_click(byval sender as object, byval e as system.eventargs)
dim list as new shapelist()
dim ps as shape
ps = new circle()
ps.setxy(10, 10)
list.addshape(ps)

ps = new rectangle()
ps.setxy(50, 50)
list.addshape(ps)

ps = list.getshape(0).clone()
ps.setxy(230, 70)
list.addshape(ps)

list.draw()
end sub
end class

此程序輸出:
draw a circle at (10, 10)
draw a rectangle at (50, 50)
draw a circle at (230, 70)

shapelist類別屬于client,在設計shapelist類別時,只能用到shape類別的信息而已;在client(如上述的form1類別)里,除了誕生對象時使用到circle和rectangle類別名稱之外,也只能用到shape類別的信息而已;這讓我們未來能不斷擴充更多子類別,如square、triangle等等。為了達到此高度擴充性,需要用到多形性(polymorphism)觀念。所以shape類別里建立了多形的基礎:

public overridable sub draw()
end sub
public overridable function clone() as shape
end function
draw( )和clone( )皆是虛擬(virtual)程序,以發揮多型(polymorphism)功能。lx及ly是圖形的左上角坐標。setxy( )可改變lx及ly值。shapelist類別的draw程序用來繪出串行中的各prototype對象圖。
vb的父類別(superclass)有兩種角色:
1) 提供一些程序給子類別繼承
2) 作為各子類別的共同接口(interface)

上述程序是兩者合一的落實途徑。如果您落實到分布式(distributed)環境里,則宜將上述兩項角色分離并各別落實之。此時必須使用vb的interface機制了。例如上述程序相當于:

'ex02.bas
imports system.componentmodel
imports system.drawing
imports system.winforms
'----------------------------------------------------
interface ishape
sub draw()
function clone() as ishape
sub setxy(byval x as integer, byval y as integer)
end interface

class shape
protected lx, ly as integer
protected sub setxy(byval x as integer, byval y as integer)
lx = x
ly = y
end sub
end class

class circle
implements ishape
inherits shape

public sub draw() implements ishape.draw
messagebox.show("drawing a circle at (" + str(lx) + ", " + str(ly) + ")")
end sub
public function clone() as ishape implements ishape.clone
clone = new circle()
end function
public sub setvalue(byval x as integer, byval y as integer) implements ishape.setxy
mybase.setxy(x, y)
end sub
end class

class rectangle
inherits shape
implements ishape

public sub draw() implements ishape.draw
messagebox.show("drawing a rectangle at (" + str(lx) + ", " + str(ly) + ")")
end sub
public function clone() as ishape implements ishape.clone
clone = new rectangle()
end function
public sub setvalue(byval x as integer, byval y as integer) implements ishape.setxy
mybase.setxy(x, y)
end sub
end class
'------------------------------------------------------------------------------------------
class shapelist
private tlist(10) as ishape
private counter as integer

public sub new()
counter = 0
end sub
public sub addshape(byval sobj as ishape)
tlist(counter) = sobj
counter = counter + 1
end sub
public function getshape(byval i as integer) as ishape
getshape = tlist(i)
end function
public sub draw()
dim i as integer
for i = 0 to counter - 1
tlist(i).draw()
next
end sub
end class
'------------------------------------------------------------------------------------------
public class form1
inherits system.winforms.form
public sub new()
mybase.new()
form1 = me
'this call is required by the win form designer.
initializecomponent()
'todo: add any initialization after the initializecomponent() call
end sub
'form overrides dispose to clean up the component list.
public overrides sub dispose()
mybase.dispose()
components.dispose()
end sub
#region " windows form designer generated code "
......
#end region
protected sub form1_click(byval sender as object, byval e as system.eventargs)
dim list as new shapelist()
dim pshape as ishape
pshape = new circle()
pshape.setxy(10, 10)
list.addshape(pshape)

pshape = new rectangle()
pshape.setxy(50, 50)
list.addshape(pshape)

pshape = list.getshape(0).clone()
pshape.setxy(230, 70)
list.addshape(pshape)

list.draw()
end sub
end class

此程序輸出:
draw a circle at (10, 10)
draw a rectangle at (50, 50)
draw a circle at (230, 70)

shape類別專心擔任幕后角色了,client及shapelist類別的設計者只看到ishape接口而已,這充分發揮了vb接口的優點。


4. prototype樣式之應用
----- 組件之設計與組裝

軟件工業逐漸往零組件或稱組件(component) 方向發展﹐未來計算機軟件人員將分為兩大群﹕對象設計者(object designer) 與對象裝配者(object assembler)。就拿vb 程序員來說﹐對象設計者負責設計類別﹐以便誕生出各式各樣之對象﹔對象裝配者能使用現有對象或將之組裝成更大之對象或系統。
依據上述加菲貓和西施的例子中﹐人們常很自然地拿自己熟悉的例子來描述他所想要的對象﹔亦即經由舉例來說明他心中的對象﹐是較合乎人們生活習慣的。反而較少以類別來描述他心中之對象。因之﹐對象設計者定義好各類別之后也應各誕生一個對象﹐當做例子(prototype) ﹐最好顯示在windows 畫面上。對象裝配者不需要具有「類別」觀念﹐只需用鼠標點取畫面上的prototype 對象﹐就能獲得一個類似的新對象了。如此﹐就可構成美好的分工情形。然而﹐在vb及java等語言中﹐對象皆是由「類別」來產生的。這會造成沖突問題﹕

u 設計者不能隨時誕生對象供裝配者使用﹐因而希望裝配者隨時藉由類別誕生對象。
u 裝配者最好不必具有類別觀念﹐因而不愿意藉由類別來誕生對象。

如何化解這個問題呢﹖答案是﹕使用prototype 樣式。

對象設計者之工作包括:
1. 設計(定義)一個form類別叫form1。
2. 設計一個應用架構(application framework)做為「設計者」與「裝配者」分工的基礎。
3. 基于架構,衍生出子類別,如circle及rect。
4. 誕生對象,存入串行shaplist中,如圖3所示。


圖3、組裝的基礎環境

對象裝配者之工作是:
點取(或使訊息)給串行中的prototype對象,由其呼叫clone( )來誕生新對象。
例如,讓「裝配者」自屏幕畫面上選取對象。circle和rectangle各定義draw( )及clone( )達到多型效果,讓「裝配者」使用起來更加方便。clone( )必傳回一個新對象。form1.click()里的指令-----

pshape = list.getshape(0).clone()
pshape.setxy(230, 70)
list.addshape(pshape)

首先,取出串行中的第0個prototype對象,此對象誕生另一個對象,由pshape代表之。在將此新對象存入串行中,如下圖所示:




圖4、組裝者依據prototype指示計算機誕生對象

最末將各prototype對象數示于畫面上。
上述例子中,把shapelist也歸為對象設計者的掌管工作之一。在實際上,shapelist常隸屬于「裝配工具」(assembly tools)內的一部份。而裝配工具的設計者,可能既非對象設計者,也非對象裝配者,而是用來協助「裝配者」使其工作效率更佳。
由于clone函數及draw( )程序的多型性,在加上clone( )能產生新對象,使得裝配工具設計者,不必顧慮到對象類別之劇增,也不必用到期類別名稱,大大減少工具程序之復雜度,這也是prototype模式的另一個重要用途。■

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 英吉沙县| 博乐市| 金乡县| 兴宁市| 林西县| 梨树县| 巴塘县| 壶关县| 丰原市| 宜都市| 行唐县| 平安县| 南安市| 阜南县| 开平市| 阳信县| 马龙县| 沁源县| 武乡县| 扶绥县| 南宁市| 舞钢市| 莎车县| 三台县| 山西省| 博湖县| 木里| 柳河县| 额敏县| 东乌珠穆沁旗| 连云港市| 平舆县| 宁蒗| 元氏县| 安国市| 石林| 滨海县| 革吉县| 兴国县| 黄山市| 福建省|