VB.Net中文教程(13) Whole-Part關係

來源:互聯網
上載者:User
教程|中文 主題: Whole-Part關係


?????????? 內容 ??????????
v 1. 對象Whole-Part關係
v 2. 組合/部分關係
v 3. 包含者/內容關係
v 4. 集合/成員關係





1. 對象Whole-Part關係

類別繼承(Class inheritance)和對象組合(Object composition)是軟體再使用(Reuse)的兩大法寶。類別繼承就是建立父、子類別之關係﹔例如﹐「學生」可分為「大學生」、「中學生」和「小學生」三類別﹐其繼承關係表徵圖如下﹕

圖1、 以UML表達類別繼承

對象組合的目的是﹕創造「綜合物件」(Composite object)﹔例如﹐醫院內含醫師和護士等﹐其組合關係表徵圖如下﹕


圖2、 以UML表達對象組合

繼承與組合兩大法寶能聯合使用﹐以組織龐大的軟體系統。例如﹐汽車分為客車、卡車、轎車等子類別﹐而且汽車內含引擎、車體、輪胎等零件﹐則此汽車系統表徵圖如下圖3和圖4﹕



圖3、 汽車的類別繼承體系


圖4、 汽車的對象組合關係

本節裡﹐將進一步分析與說明對象組合方法。尤頓(Yourdon) 認為﹐常見組合關係有三﹕
1) 組合╱部分(Assembly-parts)關係。
2) 包含╱內容(Container-contents)關係。
3) 集合╱成員(Collection-members)關係。





2. 組合/部分關係

組合/部分關係﹐常稱為APO(A part of)關係﹔例如﹐汽車是「組合」﹐其內含各零件是「部分」。門是房子的一部分﹐所以房子是「組合」﹐門是「部分」﹔此外﹐窗子也是房子的「部分」。這房子與門窗之關係﹐表徵圖如下﹕


圖5、 房子的對象組合關係

以VB表達如下﹕

'ex01.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'---------------------------------------------------------------------------------
Class House
Class Door
Public size As Double
Public Sub New(ByVal s As Double)
size = s
End Sub
End Class

Class Window
Public size As Double
Public Sub New(ByVal s As Double)
size = s
End Sub
End Class

Private dr As Door
Private win As Window
Public Sub New()
dr = New Door(50)
win = New Window(100)
End Sub
Public Sub Show()
Messagebox.Show("Door: " + str(dr.size) + " Win: " + str(win.size))
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 h As New House()
h.Show()
End Sub
End Class

以此程式輸出如下﹕
Door: 50 Win: 100


House 之對象誕生後﹐立即誕生內含之Door對象和Window對象。例如﹐宣告指令──
Dim h As New House()

此時﹐h 對象誕生了﹐其內含之dr 和win對象亦誕生了。



此h 通稱為「組合對象」(Composite object)﹐而dr 和win 則稱為「部分對象」(Component object)。這種關係具有一項特色﹕組合對象與部分對象的壽命應該是一致的。
在邏輯(Logical)意義上,這House 結構中﹐門和窗隨著房子而具有「生死與共」之親蜜關係,也就是壽命一致。在電腦實體(Physical)表達時,House 之對象並不「真正」包含Door及Window之對象﹐只是利用兩個參考指向它們。所以上圖也可想象如下:


上述兩種實體結構皆表達了「組合/部分」關係。請再看個例子:

'ex02.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'----------------------------------------------------
Class Person
Private p_name As String
Private p_age As Integer

Public Sub New(ByVal na As String, ByVal a As Integer)
p_name = na
p_age = a
End Sub
Public Function isEqual(ByVal obj As Person) As Integer
Dim k As Integer = 0
If Me.p_name = obj.p_name Then
k = 1
End If
isEqual = k
End Function
Public Sub Show()
Messagebox.Show(Me.p_name + ", " + str(Me.p_age))
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 a As New Person("Alvin", 35)
Dim b As New Person("David", 25)
a.Show()
b.Show()
Messagebox.Show(str(a.isEqual(b)))
Messagebox.Show(str(b.isEqual(New Person("David", 32))))
End Sub
End Class

此程式輸出﹕
Alvin, 35
David, 25
0
1

「組合」對象之建構者New()程式誕生「部分」對象。此a 、b 兩對象之內容為﹕






在isEqual()程式裡,兩個對象拿其p_name 值來比較。例如﹐a.p_name 值是"Alvin" ﹐而b.p_name 值是"David" ﹐所以a.isEqual(b)運算式之值為0 (False)。







3. 包含者/內容關係

上節的House 結構中﹐門和窗隨著房子而具有「生死與共」之親蜜關係。然而﹐日常生活中﹐常見類似但並不如此親蜜的情形。例如﹐飛行員坐于飛機駕駛倉內開飛機﹔司機在汽車內駕駛汽車﹔客人乘座於巴士內等等。司機不是汽車的零件﹐客人亦非巴士之組件﹐所以汽車與司機之間並非「組合/部分」關係﹔然而﹐汽車的確包含著司機﹐因之稱為「包含者/內容」(Container-contents)關係。
司機和汽車為獨立之對象﹐不像引擎一直包含於汽車內﹔於駕駛汽車時﹐司機才被包含於汽車內。顯然地﹐司機與汽車之壽命不一樣長。「包含者/內容」關係是一種特殊的組合結構﹐其表徵圖方法與「組合/部分」關係相同。例如﹐


此圖表達了﹕
◎ 汽車與引擎之間為「組合/部分」關係。
◎ 汽車與司機之間為「包含者/內容」關係。

以VB表達如下﹕

'ex03.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'----------------------------------------------------
Class Driver
Private name As String
Public Sub New(ByVal na As String)
name = na
End Sub
Public Sub Show()
MessageBox.Show("Driver: " + name)
End Sub
End Class

Class Car
Class Engine
Public model As String
Public Sub New(ByVal mdl As String)
model = mdl
End Sub
End Class

Private e As Engine
Private dr As Driver
Public Sub New()
e = New Engine("Honda")
End Sub
Public Sub assignTo(ByVal d As Driver)
dr = d
End Sub
Public Sub Show()
MessageBox.Show("Engine: " + e.model)
dr.Show()
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 civic As New Car()
Dim d1 As New Driver("Wang")
Dim d2 As New Driver("Kao")
civic.assignTo(d1)
civic.Show()
civic.assignTo(d2)
civic.Show()
End Sub
End Class

此程式輸出﹕
Model: Honda
Driver: Wang
Model: Honda
Model" Kao

Car之對象誕生後﹐也誕生Engine之對象e ﹔同時立即指定司機﹐如下指令﹕

Dim civic As New Car()
Dim d1 As New Driver("Wang")
.....
civic.assignTo(d1)
.....

日常生活中的常見情況﹕汽車對象誕生時﹐不須立即指定司機對象。例如﹐汽車出廠時或閑置時並無司機﹐且汽車經常更換司機。此情形下﹐應先誕生civic對象和d1對象,如下:



此時,未立即指定司機﹔而必要時才以assignTo()程式指定司機。例如,將d1指定給civic對象﹐就令civic內之參考變數dr指向d1 對象,如下:



上述程式裡,d1、d2及civic 對象之間﹐誰先誕生並無關緊要﹐各獨立存在。指令──civic.assignTo(d1) 將d1司機指定給civic 對象﹔另一指令──civic.assignTo(d2)表示﹕改由d2擔任civic 之司機。
此Car 類別以參考變數e來指向Engine之對象。現在﹐茲拿上節的Person類別做為例子﹐如果某人(Person 之對象)結婚了﹐就有配偶﹔反之尚未結婚時﹐則無配偶。此時﹐應將Person類別之定義修改如下﹐以表達這種「配偶」關係﹕

'ex04.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
'----------------------------------------------------
Class Person
Private p_name As String
Private p_age As Integer
Private p_spouse As Person

Public Sub New(ByVal na As String, ByVal a As Integer)
p_name = na
p_age = a
End Sub
Public Sub spouse(ByVal sp As Person)
p_spouse = sp
sp.p_spouse = Me
End Sub
Public Sub Show()
Messagebox.Show(Me.p_name + ", " + str(Me.p_age)
+ ", sp: " + Me.p_spouse.p_name)
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 x As New Person("David", 32)
Dim y As New Person("Hellen", 24)
x.spouse(y)
x.Show()
y.Show()
End Sub
End Class

此程式輸出﹕
David, 32, sp: Hellen
Hellen, 24, sp: David

資料成員p_spouse指向配偶﹐而配偶亦為Person之對象。所以p_spouse之型態應為Person。一個人剛誕生時並無配偶﹐到結婚時才有配偶﹐所以藉spouce()來建立配偶關係。對象x 與y 結婚之後﹐互為對方之配偶。所以x.p_spouse指向y ﹐而y.p_spouse則指向x 。此時﹐x 和y 之內容如下﹕



於是這Person類別表達了「婚姻」關係。






4. 集合/成員關係

集合意謂著「團體」(Group) ﹐由其成員(Member)組成的群體。例如﹐學校裡的社團內有團員﹔公司的銷售部含有推銷人員。這團體並不像汽車實際包含著司機﹐而只是其成員之集合而已。這情形﹐統稱為「集合/成員」(Collection-members)關係。
有趣的是﹕在企業活動中﹐人們規劃的方案﹐含許多小方案﹔則大方案是由小方案所組成。例如﹐東北亞旅行團的行程表包括在日本的觀光行程、在韓國的觀光行程和在香港的觀光行程。這總行程表表徵圖如下﹕



總行程是次行程(或稱段行程)之集合﹐這是「集合/成員」關係。



此外﹐棒球隊是由經理、教練和球員組成﹕訂單中含若干產品項目﹐皆為集合/成員關係。實際寫程式時﹐不需明確劃分「包含者/內容」和「集合/成員」兩種關係。其原因是﹕集合與成員之間亦可互為獨立﹐不具「生死與共」之親蜜關係﹔例如﹐「香港觀光行程」是獨立存在的﹐它既可含於東北亞總行程中﹐又可含於東南亞旅行團的總行程中。因之﹐「集合/成員」關係是一種特殊的「組合」(Composition) 結構。
茲拿上節Person類別做為例子﹐如果Person之對象會加入Club(俱樂部)成為俱樂部的會員﹐則Club與Person之關係為「集合/成員」關係。茲定義Club類別如下﹕

'ex05.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
Imports System.Collections
'----------------------------------------------------
Class Person
Private p_name As String
Private p_age As Integer

Public Sub New(ByVal na As String, ByVal a As Integer)
p_name = na
p_age = a
End Sub
Public Sub display()
Messagebox.Show(Me.p_name + ", " + str(Me.p_age))
End Sub
End Class

Class Club
Private c_name As String
Private pa As ArrayList

Public Sub New(ByVal na As String)
c_name = na
pa = New ArrayList()
End Sub
Public Sub join(ByVal p As Person)
pa.Add(p)
End Sub
Public Sub display()
Messagebox.Show("Club: " + Me.c_name + " has member:")
Dim p As Person
For Each p In pa
p.display()
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 x As New Club("sogo")
Dim a As New Person("Alvin", 32)
Dim b As New Person("Judy", 28)
x.join(a)
x.join(b)
x.display()
End Sub
End Class


此程式輸出﹕
Club: sogo has member:
Alvin, 32
Judy, 28

c_name 指向Strclass之對象﹐這對象內含俱樂部之名稱。pa指向ArrayList之對象﹐這對象可包含許多會員(Person)對象。join()程式將Person之對象存入pa所指的ArrayList對象中。
Club之對象含ArrayList之對象﹐此集合對象(Collections)含有Person之對象﹐表達了「集合/成員」關係。例如﹐x 對象內含a 和b 對象。



此圖表示﹕"sogo"俱樂部共有"Alvin" 和"Judy"兩個會員﹐亦即x 是「集合」﹐而a 和b 是「成員」(Member)。
值得注意﹕這軟體是利用已有類別──Strclass及Integer組合成應用類別──Person。再利用Person類別及ArrayList 類別組合成更複雜之應用類別──Club。未來﹐可利用Club及其它類別構築更大的應用類別﹐依此類推﹐便能創造龐大又可靠的軟體了。例如:

'ex06.bas
Imports System.ComponentModel
Imports System.Drawing
Imports System.WinForms
Imports System.Collections
'----------------------------------------------------
Class Person
Private p_name As String
Private p_age As Integer
Public Sub New(ByVal na As String, ByVal a As Integer)
p_name = na
p_age = a
End Sub
Public Sub display()
Messagebox.Show(Me.p_name + ", " + str(Me.p_age))
End Sub
End Class

Class Club
Private c_name As String
Private pa As ArrayList

Public Sub New(ByVal na As String)
c_name = na
pa = New ArrayList()
End Sub
Public Sub join(ByVal p As Person)
pa.Add(p)
End Sub
Public Sub display()
Messagebox.Show("Club: " + Me.c_name + " has member:")
Dim p As Person
For Each p In pa
p.display()
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 x(2) As Club
x(0) = New Club("sogo")
x(1) = New Club("gold")
Dim a As New Person("Alvin", 32)
Dim b As New Person("Judy", 28)
Dim c As New Person("Bob", 38)
x(0).join(a)
x(0).join(b)
x(1).join(b)
x(1).join(c)
x(0).display()
x(1).display()
End Sub
End Class

此程式輸出:

Club: sogo has member:
Alvin, 32
Judy, 28
Club: gold has member:
Judy, 28
Bob, 38

組合對象x 含"sogo"及"gold"兩俱樂部﹐其中"gold"俱樂部擁有兩個會員──"Alvin" 及"Judy"﹐而"sogo"俱樂部擁有兩位會員──"Judy"及"Bob" 。x(0)代表"sogo"俱樂部﹐s(1)代表"gold"俱樂部﹐所以指令── s(0).join( a ) 表示a 加入"gold"俱樂部﹐成為其會員。n



相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。