孫學(xué)波,李昕妍
(遼寧科技大學(xué) 軟件學(xué)院,遼寧 鞍山114051)
目前,應(yīng)用組件開(kāi)發(fā)應(yīng)用軟件已經(jīng)成為主流的軟件開(kāi)發(fā)方法[1]。當(dāng)前流行的各種軟件開(kāi)發(fā)架構(gòu)體系,如 Microsoft Visual Studio.Net和Eclipse等,均提供了大量的可復(fù)用的軟件組件,以支持各種應(yīng)用軟件的開(kāi)發(fā)。應(yīng)用現(xiàn)有組件不僅可以有效地降低軟件開(kāi)發(fā)的難度,而且也有利于提高軟件開(kāi)發(fā)的效率和質(zhì)量。這些軟件組件基本能夠滿足大部分應(yīng)用領(lǐng)域的功能需求,如基于數(shù)據(jù)庫(kù)的管理信息系統(tǒng)領(lǐng)域等。但對(duì)于某些特殊的應(yīng)用領(lǐng)域,卻無(wú)法找到合適的軟件組件來(lái)滿足這些特殊的需求。因此,獨(dú)自開(kāi)發(fā)滿足這些特殊需求的可復(fù)用的軟件組件就成為一件十分有意義的事了[2-5]。
在鐵路運(yùn)輸管理系統(tǒng)[6-8]項(xiàng)目中,我們遇到了一個(gè)需要提供車(chē)輛分布的可視化表示和交互式地進(jìn)行車(chē)輛調(diào)度作業(yè)的特殊需求。為更好地支持這一需求,我們提出了一個(gè)基于多隊(duì)列[9]的分布式鐵路車(chē)輛分布可視組件的概念,并給出了其具體的設(shè)計(jì)與實(shí)現(xiàn)。應(yīng)用這個(gè)組件成功地解決了項(xiàng)目中的車(chē)輛分布的可視化問(wèn)題和車(chē)輛調(diào)度作業(yè)問(wèn)題。
為完整地描述組件的邏輯結(jié)構(gòu),首先給出與本組件相關(guān)的一些基本概念。
隊(duì)列元素:本文中的隊(duì)列元素是指一個(gè)實(shí)現(xiàn)了某個(gè)特定接口的實(shí)體對(duì)象,用于描述現(xiàn)實(shí)世界中的某個(gè)客觀實(shí)體。在應(yīng)用實(shí)例中,用于表示鐵路車(chē)輛實(shí)體。隊(duì)列元素所在的隊(duì)列為其所處的某種”環(huán)境”,其特殊性在于元素與其所處的環(huán)境之間存在某種順序和位置上的關(guān)聯(lián)或約束。
本文強(qiáng)調(diào)以下兩種約束:
(1)位置約束:每一個(gè)隊(duì)列元素在其所在的隊(duì)列中均具有一個(gè)位置屬性,這個(gè)位置不一定決定于元素本身的屬性,它可能更多地決定于人對(duì)與隊(duì)列元素對(duì)應(yīng)的客觀實(shí)體的管理 (如車(chē)輛在股道上的位置或貨物在貨位上的位置)。顯然這個(gè)屬性是可以并且需要被改變的。
(2)接口約束:為實(shí)現(xiàn)對(duì)隊(duì)列元素實(shí)施有效的管理,就需要在組件內(nèi)部對(duì)隊(duì)列元素定義一系列操作,同時(shí)又希望這些操作與隊(duì)列元素實(shí)體的具體屬性無(wú)關(guān)。因此本組件僅為隊(duì)列元素定義了一個(gè)抽象類,從而省掉了其對(duì)應(yīng)實(shí)體類的具體實(shí)現(xiàn),其具體實(shí)現(xiàn)則留到其具體的應(yīng)用中。
隊(duì)列:所謂隊(duì)列是一個(gè)由隊(duì)列元素構(gòu)成的線性表,其插入操作限制在表的一端進(jìn)行,而刪除則限制在表的另一端進(jìn)行。隊(duì)列的操作則包括初始化、進(jìn)隊(duì)、出隊(duì)、判斷隊(duì)列是否空、取隊(duì)列元素和隊(duì)列的可視化等。
雙向隊(duì)列:所謂雙向?qū)α惺且粋€(gè)由隊(duì)列元素組成的線性表。其插入和刪除操作則限制在隊(duì)列的兩端進(jìn)行。雙向隊(duì)列的操作與隊(duì)列操作基本相同,不同的是僅僅放寬了對(duì)插入和刪除位置的限制。一個(gè)雙向隊(duì)列用于表示現(xiàn)實(shí)世界中的某個(gè)實(shí)體或?qū)嶓w集,如在本項(xiàng)目案例中,表示一條“股道”。顯然,雙向隊(duì)列僅是對(duì)隊(duì)列概念的一個(gè)擴(kuò)充。
多重雙向隊(duì)列[9]:所謂的多重雙向隊(duì)列是一個(gè)由若干個(gè)雙向隊(duì)列組合而成的一個(gè)集合。也可以說(shuō)多重雙向隊(duì)列是一組實(shí)現(xiàn)了某個(gè)特定接口的對(duì)象構(gòu)成的集合,這些對(duì)象分布在若干個(gè)雙向隊(duì)列中,而所謂的多重雙向隊(duì)列就是由這樣一組多重雙向隊(duì)列聚合而成的一個(gè)對(duì)象。
多重雙向隊(duì)列的實(shí)質(zhì)是一組由多個(gè)雙向隊(duì)列構(gòu)成的集合,它對(duì)應(yīng)于現(xiàn)實(shí)世界中的某個(gè)特定的實(shí)體或?qū)嶓w集。如果一個(gè)隊(duì)列表示某調(diào)車(chē)場(chǎng)里面的一條股道,那么,這個(gè)隊(duì)列則對(duì)應(yīng)了一個(gè)實(shí)體集 (一組車(chē)輛),它也對(duì)應(yīng)了一個(gè)特定的實(shí)體股道。而一個(gè)隊(duì)列集合則可以表示一個(gè)或多個(gè)調(diào)車(chē)場(chǎng) (此時(shí)也可以稱為作業(yè)區(qū))。此時(shí)則更容易理解,多重雙向隊(duì)列概念所具有的現(xiàn)實(shí)意義。
多重雙向隊(duì)列從概念上來(lái)說(shuō)是一組雙向隊(duì)列構(gòu)成的集合,它實(shí)際上是現(xiàn)實(shí)世界中一組邏輯相關(guān)的有序元素集合構(gòu)成的集合。元素在某個(gè)隊(duì)列中的相對(duì)位置則描述了元素與元素、元素與隊(duì)列以及元素與多重雙向隊(duì)列之間的相對(duì)關(guān)系。
所以,多重雙向隊(duì)列上的操作就應(yīng)該是以特定方式描述、展現(xiàn)和維護(hù)它們之間的關(guān)系的一組操作集合。
本組件定義的多重雙向隊(duì)列的主要操作如下:
(1)初始化:初始化多重雙向隊(duì)列,計(jì)算每個(gè)雙向隊(duì)列的大小、顯示位置等數(shù)據(jù)。初始化每個(gè)雙向隊(duì)列對(duì)象。
(2)可視化:顯示每一個(gè)雙重隊(duì)列的可視屬性及其隊(duì)列中的元素。
(3)修改隊(duì)列元素:用于修改指定元素的實(shí)體屬性。
(4)生成隊(duì)列操作命令列表:與用戶交互編制用于在不同隊(duì)列間轉(zhuǎn)移元素的 “隊(duì)列操作命令列表”。
(5)執(zhí)行隊(duì)列操作命令列表:執(zhí)行當(dāng)前的隊(duì)列操作命令列表,修改隊(duì)列元素位置。
多重隊(duì)列操作:首先,把某個(gè)雙向隊(duì)列的一個(gè)入隊(duì)或出隊(duì)操作稱作一個(gè)隊(duì)列操作命令。其次,把一組邏輯上相關(guān)的隊(duì)列操作命令稱為一個(gè)多重隊(duì)列操作。顯然,一個(gè)多重隊(duì)列操作實(shí)際上就是車(chē)輛調(diào)度系統(tǒng)中的一個(gè)調(diào)車(chē)作業(yè)計(jì)劃,它可用于實(shí)施一次車(chē)輛調(diào)度作業(yè)。
例如要將第三個(gè)隊(duì)列中的第3個(gè)元素開(kāi)始的10個(gè)元素移動(dòng)到第五個(gè)隊(duì)列的第3個(gè)元素和第4個(gè)元素之間。它所需要的多重隊(duì)列操作的內(nèi)容見(jiàn)表1。
表1 多重隊(duì)列操作示例
組件類 (MQComponent):在.NET架構(gòu)下,組件被定義為一個(gè)Usercontrol類的派生類對(duì)象,它負(fù)責(zé)提供組件的外部接口,由一組預(yù)先定義好的一組屬性、操作和事件組成。
組件的用戶界面類 (GrahicsUserInterface):組件的應(yīng)用程序界面,用于實(shí)現(xiàn)多重雙向隊(duì)列的可視化表示,整個(gè)界面由3個(gè)可視的Panel對(duì)象元素組成,分別用于實(shí)現(xiàn)每個(gè)隊(duì)列、每個(gè)隊(duì)列的隊(duì)列元素以及隊(duì)列元素的順序的可視化表示。
圖1 給出了組件的用戶界面的結(jié)構(gòu),其中Queue panel用于顯示多重隊(duì)列 (即車(chē)輛場(chǎng)地)的結(jié)構(gòu),Queue Element Panel負(fù)責(zé)顯示隊(duì)列元素,即車(chē)輛。其具體實(shí)例可參見(jiàn)圖。
圖1 組件的界面結(jié)構(gòu)
多重隊(duì)列類 (MultiQueue):作為用戶多重雙向隊(duì)列類的基類,定義了用戶多重雙向隊(duì)列類的接口,是本組件的核心類。在結(jié)構(gòu)中作為組件對(duì)象的一個(gè)組成對(duì)象,表示組件中最高層次的隊(duì)列元素集合。
雙向隊(duì)列類 (Bidirectional Queue):作為用戶雙向隊(duì)列類的基類,定義了用戶雙向隊(duì)列類的接口,是多重雙向隊(duì)列對(duì)象的組成對(duì)象,表示一個(gè)用戶隊(duì)列元素的集合。
隊(duì)列元素類 (QueueElement):作為用戶隊(duì)列元素類的基類,定義了組件所需的隊(duì)列元素類的接口,是組件中最基本的組成元素對(duì)象,也是組件各種操作的最基本的單位元素。
多重隊(duì)列操作類 (OperationList);由一組隊(duì)列操作命令組成的列表,用于改變組件中指定隊(duì)列的指定元素的位置。
圖2 給出了組件中定義的主要類和它們之間的關(guān)系,其中Usercontrol類是一個(gè).net組件類,用于定義一個(gè)封裝相關(guān)的現(xiàn)有控件并提供其自身邏輯的新控件提供基類。
圖2 組件中各個(gè)類之間的關(guān)系
MQComponent是Usercontrol類[1]的派生類,用于實(shí)現(xiàn)本組件自身的業(yè)務(wù)邏輯。GraphicsUserInterface類是本組件的用戶界面類,用于實(shí)現(xiàn)本組件中多重雙向隊(duì)列的可視化和與用戶的交互操作。
MultiQueue,Bidirectional Queue和 QueueElement是本組件自定義的3個(gè)類,分別表示本組件的多重雙向隊(duì)列類、雙向隊(duì)列類和隊(duì)列元素類。
MultiQueueCommandList、MultiQueueCommand、PictureOfCommand為命令列表類和命令類和命令圖形類,用于管理隊(duì)列操作命令列表,定義了組件的主要操作。
最后的兩個(gè)類 MoveCommandList、MoveCommand是組件提供給用戶的操作列表類。也是組件的一個(gè)外部接口。
為了擴(kuò)展組件的適用范圍,本組件以基類的形式對(duì)外提供了一組外部接口。用戶可通過(guò)繼承和覆蓋的方式使用這些接口使其業(yè)務(wù)邏輯與組件提供的服務(wù)進(jìn)行有效的結(jié)合。
本組件提供的接口包括如下3種:
(1)接口是組件在運(yùn)行時(shí)與終端用戶 (操作員)交互所需的操作員接口。這個(gè)接口由一組圖形化交互操作組成,包括查看和修改隊(duì)列元素的屬性、刪除隊(duì)列元素、選擇隊(duì)列元素、改變隊(duì)列元素位置等操作。
(2)接口是組件在運(yùn)行時(shí)與客戶程序交互所需的動(dòng)態(tài)接口。這個(gè)接口主要由組件類定義的一組屬性、方法和事件組成。
(3)接口開(kāi)發(fā)客戶程序時(shí)組件與客戶程序員交互所需要的靜態(tài)接口,這個(gè)接口由一組組件對(duì)外公開(kāi)的類組成。開(kāi)發(fā)客戶程序時(shí)客戶可以通過(guò)繼承的方式使用這個(gè)接口。
客戶程序接口:運(yùn)行時(shí)與客戶程序交互的動(dòng)態(tài)接口主要通過(guò)在組件類 (MQComponent)中定義的一組屬性、方法和事件來(lái)實(shí)現(xiàn)。其基本的屬性、方法和事件概要敘述如下。
組件主要屬性包括:隊(duì)列元素的顯示寬度、高度、字體、字號(hào)、顏色、線型、線寬和對(duì)齊方式等屬性。表示隊(duì)列元素屬性和狀態(tài)的圖像列表等屬性。
組件類的方法包括:初始化、添加多重雙向隊(duì)列。
組件的主要方法見(jiàn)表2。
表2 組件的主要方法
組件類的主要事件見(jiàn)表3。
表3 組件的主要事件
程序員接口:設(shè)計(jì)時(shí)與客戶程序員交互所需要的靜態(tài)接口主要由組件提供的若干個(gè)基類組成,這些類可以作為用戶程序的某些類的基類。
這些類主要包括多重雙向隊(duì)列類 (MultiQueue)、雙向隊(duì)列類 (Bidirectional Queue)、隊(duì) 列元素 類 (QueueEle-ment)和操作列表類 (OperationList)。這些類的基本定義如下:
多重隊(duì)列類MultiQueue:在多重隊(duì)列類MultiQueue的設(shè)計(jì)中,參照了GOF設(shè)計(jì)模式中的組合模式,使得組件實(shí)例中可以包含多個(gè)多重雙向隊(duì)列,使得組件實(shí)際上包含了一個(gè)多重雙向隊(duì)列集合。
圖3 所示的類圖中,ID、Name為多重隊(duì)列的標(biāo)識(shí)符和名稱屬性;left,top,width和height等為多重隊(duì)列的顯示屬性,其值組件的初始化算法自動(dòng)生成;pQueue為某個(gè)雙向?qū)α械囊?,表示多重?duì)列中的隊(duì)列集合;屬性next是某個(gè)多重隊(duì)列的引用,表示一個(gè)組件實(shí)例中的多重隊(duì)列可以是一個(gè)復(fù)合對(duì)象。Draw(Grahpics g)是一個(gè)虛方法,用于顯示多隊(duì)列的名稱等屬性;AddQueue(BiQueue q)方法用于向多重隊(duì)列中添加一個(gè)雙向?qū)ο?;SelectElement(Crectangle rect)和UnSelectElement()方法用于實(shí)現(xiàn)交互式地選擇隊(duì)列元素。
雙向隊(duì)列類BiQueue:雙向隊(duì)列類則相對(duì)簡(jiǎn)單,主要封裝了雙向類的基本操作,包括入隊(duì)、出隊(duì)、顯示、選擇等操作??蛻舫绦蚩梢砸岳^承這個(gè)類的方式使用該組件。其基本定義如下:
圖3 多重隊(duì)列類類圖
圖4 所示的類圖中,ID、Name為隊(duì)列的標(biāo)識(shí)符和名稱屬性;left,top,width和height等為隊(duì)列的顯示屬性;Next是某個(gè)雙向隊(duì)列的引用,用于鏈接多重隊(duì)列中的雙向隊(duì)列。Biqueue(string ID,string Name)為雙向隊(duì)列類的構(gòu)造函數(shù);Draw(Grahpics g)用于顯示隊(duì)列的名稱等屬性;EnterQueue(QueueElement e,int direction)和DeleteQueue(int direction)方法用于添加和刪除隊(duì)列元素;Select(CRectangle rect)和UnSelect()方法用于交互式地選擇隊(duì)列元素;CalculateLayout()用于計(jì)算隊(duì)列元素的顯示位置。
圖4 雙向隊(duì)列類類圖
隊(duì)列元素類QueueElement:隊(duì)列元素為一個(gè)抽象類,用于表示具體業(yè)務(wù)邏輯所需要的實(shí)體類。客戶程序必須繼承這個(gè)類。具體設(shè)計(jì)如圖5所示。圖中,屬性ID、Name為隊(duì)列元素的標(biāo)識(shí)符和名稱;IsSelected和IsModified為兩個(gè)標(biāo)志,用于標(biāo)記隊(duì)列元素的被選中和被修改等狀態(tài)。該類的方法中,Select和UnSelect用于選擇隊(duì)列元素,IsSelected()和IsModified()用于返回該隊(duì)列元素的選擇狀態(tài)和修改狀態(tài);Draw(Graphics g)、Modify()和Display()等方法均設(shè)計(jì)為虛函數(shù),用戶可以在派生類中覆蓋它們。Draw(Graphics g)方法用于顯示隊(duì)列元素的名稱和ID,Modify()和Display()方法是兩個(gè)純虛函數(shù),這兩個(gè)函數(shù)允許用戶在派生類中實(shí)現(xiàn)它們,以便用戶以自己的方式顯示和修改隊(duì)列元素的屬性。
圖5 隊(duì)列元素類類圖
隊(duì)列操作命令列表類 (MoveCommandlist):隊(duì)列操作命令列表類封裝了一組隊(duì)列操作命令,用于通知用戶多重雙向隊(duì)列內(nèi)部元素位置變化所需要的操作命令細(xì)節(jié),實(shí)際應(yīng)用中這個(gè)操作列表可能會(huì)被傳遞到現(xiàn)場(chǎng)或某中自動(dòng)化設(shè)備,完成對(duì)隊(duì)列元素實(shí)體的實(shí)際操作,改變實(shí)體元素的位置。組件內(nèi)部也用于更新組件中指定元素的當(dāng)前位置。
隊(duì)列操作命令數(shù)據(jù)結(jié)構(gòu)見(jiàn)表4。
命令列表類可以用一個(gè)簡(jiǎn)單的由上述隊(duì)列操作命令數(shù)據(jù)結(jié)構(gòu)組成的線性表來(lái)實(shí)現(xiàn)。特別要注意的是生成過(guò)程中要校驗(yàn)每一條命令的正確性和整個(gè)命令列表的正確性問(wèn)題。
表4 隊(duì)列操作命令數(shù)據(jù)結(jié)構(gòu)
這個(gè)算法根據(jù)導(dǎo)入到多重雙向隊(duì)列中的雙向隊(duì)列的個(gè)數(shù)和層次結(jié)構(gòu)以及隊(duì)列容量計(jì)算每個(gè)隊(duì)列的大小和位置。為隊(duì)列的可視化過(guò)程做準(zhǔn)備。
此算法由組件中的 MultiQueueComponent、MultiQueue和BiQueue這3種類型的對(duì)象協(xié)同實(shí)現(xiàn)。3種對(duì)象間的協(xié)作關(guān)系如圖6所示。
圖6 多重雙向隊(duì)列組件的初始化過(guò)程
多重雙向隊(duì)列組件初始化的算法由分布在各個(gè)類中的多個(gè)操作實(shí)現(xiàn)。初始化算法的實(shí)現(xiàn)由組件類MultiQueue-Component、多重雙向隊(duì)列類 MultiQueue和雙向隊(duì)列類BiQueue的同名操作CalculateLaout協(xié)作完成。具體實(shí)現(xiàn)如下。
算法一:多重雙向隊(duì)列組件的初始化
void MultiQueueComponent::CalculateLaout()
{
1計(jì)算并設(shè)置每個(gè)界面元素的顯示位置
2計(jì)算組件界面的顯示位置。
MultiQueue*p=mMultiQueue;
int left=0;
//設(shè)置組件中每一個(gè)多重雙向隊(duì)列的顯示位置
for(p=mMultiQueue;p?。絥ull;p=p->next;)
left=p->CalculateLaout(left);
Width=left;
Height=EHeight * (LengthOfQueue+2);
}
int MultiQueue::CalculateLaout(int left)
{
BidirectionalQueue*p;
int w=0;Left=left;Top=0;//多重雙向隊(duì)列的
for(p=mBDQueue;p?。絥ull;p=p.next)
{
//設(shè)置多重雙向隊(duì)列中每一個(gè)雙向隊(duì)列的顯示位置
left=p->CalculateLaout(left);
w=w+EWidth;
}
Width=w;Height=mComponent.EHeight;
return left;//返回下個(gè)多重雙向隊(duì)列的左邊界
}
int BiQueue::CalculateLaout(int left)
{
//設(shè)置隊(duì)列標(biāo)題的顯示位置
Top=0;Left=left;Width=EWidth;Height=EHeight;
for(int i=0,top=0;i<LengthOfQueue;i++)
{
//設(shè)置每個(gè)隊(duì)列元素的顯示位置
Rect [i]=new Rectangle(left,top,EWidth,EHeight);
top=top+EHeight;
}
return left+Width;//返回下個(gè)隊(duì)列的左邊界
}
其它算法的實(shí)現(xiàn)與此算法類似,不再給出細(xì)節(jié)。
多重雙向隊(duì)列的可視化過(guò)程負(fù)責(zé)根據(jù)初始化的計(jì)算結(jié)果實(shí)現(xiàn)組件中各個(gè)可視元素包括多重雙向隊(duì)列、每個(gè)雙向隊(duì)列和隊(duì)列中每個(gè)隊(duì)列元素的可視化。可視化過(guò)程如圖7所示。
圖7 多重雙向隊(duì)列組件的可視化過(guò)程
多重雙向隊(duì)列組件的可視化結(jié)果可參見(jiàn)圖7,圖中第一行顯示實(shí)例中每個(gè)多重雙向隊(duì)列,第二行則列出了每個(gè)多重雙向隊(duì)列的子隊(duì)列。組件中每一列表示一個(gè)雙向隊(duì)列,每個(gè)隊(duì)列中的每個(gè)單元格表示一個(gè)隊(duì)列元素,空白的單元格表示該位置空。
組件中,隊(duì)列操作命令列表的使用過(guò)程被分成3個(gè)步驟進(jìn)行:首先,是隊(duì)列操作命令列表的編制過(guò)程。其次,輸出生成的隊(duì)列操作命令列表。在組件外部根據(jù)生成的隊(duì)列操作命令列表完成隊(duì)列元素對(duì)應(yīng)實(shí)體的位置的改變。最后,組件再依據(jù)實(shí)體的實(shí)際位置改變組件內(nèi)部隊(duì)列元素的位置。
本組件提供了兩種隊(duì)列操作命令列表的生成方法。一種是使用對(duì)話框由用戶人工編制的生成方法。另一種是基于圖形的交互式生成方法。這兩種方法各有優(yōu)缺點(diǎn),可以供用戶選擇使用。但后一種方法是一種自然的工作方法,更符合用戶的日常工作習(xí)慣。它們使用戶可以應(yīng)用組件提供的功能生成用戶所需要的隊(duì)列操作命令列表,從而幫助用戶完成用戶所需要的隊(duì)列元素重排任務(wù)。由于篇幅限制,下面僅給出基于圖形的生成方法。
(1)隊(duì)列操作命令的可視化:組件中,為了表達(dá)用戶對(duì)隊(duì)列元素的操作意圖,組件定義了一個(gè)規(guī)則的圖形,來(lái)表示一個(gè)對(duì)指定的隊(duì)列元素要進(jìn)行的隊(duì)列操作。這樣,一個(gè)完整的隊(duì)列操作命令列表就可以用一組這樣的隊(duì)列操作圖形來(lái)直觀地加以描述。而按照進(jìn)出隊(duì)列的位置不同,組件定義了4種形狀不同的圖形表示。
一個(gè)隊(duì)列操作圖形一個(gè)矩形和一個(gè)由六條直線段和兩條Bezier曲線封閉而成的一個(gè)路徑組成。矩形區(qū)域標(biāo)識(shí)了被選定的隊(duì)列元素,路徑的控制點(diǎn)由組件使用橡皮筋技術(shù)在與用戶的交互過(guò)程中動(dòng)態(tài)生成,路徑中貝塞爾曲線兩端的一階曲率則直觀地標(biāo)記了隊(duì)列操作的方向,箭頭端點(diǎn)指定了元素要移入的隊(duì)列。根據(jù)雙向隊(duì)列的定義,容易知道一個(gè)隊(duì)列操作圖形可能有4種不同的基本形狀。
具體圖例如圖8所示。圖中每個(gè)圖例的含義是非常直觀的。如圖8中的圖例1表示按向上方向取出4個(gè)元素按向下方向放入箭頭指向的隊(duì)列。圖例3表示按向下方向取出4個(gè)元素按向下方向放入箭頭指向的隊(duì)列。
圖8 隊(duì)列操作命令的圖形表示
另外,一個(gè)隊(duì)列操作命令圖形也可以包含多組不同的隊(duì)列元素。如圖9所示。
圖9 隊(duì)列操作命令圖圖示
組件中,隊(duì)列操作命令圖形由PictureOfCommand類實(shí)現(xiàn),它與其它類的關(guān)系見(jiàn)圖2。
(2)多重隊(duì)列操作的交互式生成:這樣,任何一個(gè)對(duì)隊(duì)列元素位置改變的意圖 (隊(duì)列操作命令)就可以由一組既定的隊(duì)列元素操作圖形來(lái)加以描述,所以這就使得用戶可以通過(guò)創(chuàng)建一組這樣的隊(duì)列元素圖形來(lái)實(shí)現(xiàn)其要對(duì)隊(duì)列元素位置的修改。組件內(nèi)部還實(shí)現(xiàn)了根據(jù)一組圖示生成和導(dǎo)出與之等價(jià)的隊(duì)列操作命令列表的功能,該功能以激活一個(gè)特定事件的方式將這個(gè)操作列表傳遞給客戶程序。
圖9 給出了一個(gè)完整的隊(duì)列操作命令圖形。圖10給出了圖9中隊(duì)列操作命令的執(zhí)行結(jié)果。表5給出了圖9中隊(duì)列操作命令導(dǎo)出的對(duì)列操作列表。
另外,根據(jù)這個(gè)隊(duì)列操作命令列表修改相應(yīng)隊(duì)列元素位置的算法顯然是很容易實(shí)現(xiàn)的。
圖10 隊(duì)列操作命令的執(zhí)行結(jié)果
表5 生成的調(diào)車(chē)作業(yè)計(jì)劃
在實(shí)際的鐵路運(yùn)輸系統(tǒng)開(kāi)發(fā)項(xiàng)目中,應(yīng)用本組件成功的構(gòu)建了一個(gè)車(chē)輛分布和車(chē)輛調(diào)度操作的分布式可視化操作平臺(tái),并以這個(gè)平臺(tái)為基礎(chǔ)實(shí)現(xiàn)了幾乎所有車(chē)輛調(diào)度作業(yè)的可視化操作,同時(shí)以此平臺(tái)為基礎(chǔ)構(gòu)建了該項(xiàng)目的整體架構(gòu),實(shí)現(xiàn)了車(chē)輛調(diào)度和管理的數(shù)字化[4]。
圖11 基于組件的鐵路運(yùn)輸系統(tǒng)的體系結(jié)構(gòu)
圖11 給出了基于組件的鐵路運(yùn)輸系統(tǒng)的體系結(jié)構(gòu),該體系結(jié)構(gòu)運(yùn)用了本文描述的軟件組件,圖中的 “車(chē)輛分布組件”就是本文描述的車(chē)輛分布組件的一個(gè)應(yīng)用實(shí)例。
這個(gè)組件與結(jié)構(gòu)中其它各組件相互協(xié)作構(gòu)了一個(gè)完整的分布式鐵路運(yùn)輸管理系統(tǒng)。
圖12 給出了鐵路運(yùn)輸管理系統(tǒng)項(xiàng)目中的一個(gè)組件應(yīng)用實(shí)例,它表示了某作業(yè)區(qū)某一時(shí)刻的車(chē)輛分布情況。
在該應(yīng)用中,每一個(gè)組件實(shí)例被映射為某一個(gè)作業(yè)區(qū),一個(gè)多重雙向隊(duì)列被映射為一個(gè)車(chē)場(chǎng),一個(gè)雙向隊(duì)列被映射為一條股道,而一個(gè)隊(duì)列元素則被映射為一個(gè)車(chē)輛。而一個(gè)組件實(shí)例上的一個(gè)隊(duì)列操作命令列表實(shí)例則被映射為一個(gè)作業(yè)區(qū)上一次車(chē)輛調(diào)度作業(yè)的調(diào)車(chē)作業(yè)計(jì)劃。系統(tǒng)中所有組件實(shí)例構(gòu)成了整個(gè)系統(tǒng)的一個(gè)完整的車(chē)輛分布的可視化分布和調(diào)度平臺(tái)。項(xiàng)目中該組件的各個(gè)實(shí)例與項(xiàng)目中其它類型的組件相互配合則構(gòu)成了整個(gè)鐵路系統(tǒng)中完整的車(chē)輛分布模型,從而實(shí)現(xiàn)了整個(gè)系統(tǒng)中車(chē)輛的實(shí)時(shí)的和精確的管理。
圖12 車(chē)輛分布組件應(yīng)用實(shí)例
由于篇幅關(guān)系,本文僅概括性地給出本組件的主要設(shè)計(jì)思路和實(shí)現(xiàn)方法而忽略了很多技術(shù)細(xì)節(jié)。
本文所述的方法是從實(shí)際案例中提煉總結(jié)出來(lái)的,在實(shí)際項(xiàng)目中,這個(gè)方法有效地解決了項(xiàng)目中面臨的諸如軟件通用性等多方面的技術(shù)難題,提高了項(xiàng)目的開(kāi)發(fā)效率和質(zhì)量,同時(shí)也極大地降低了軟件開(kāi)發(fā)的成本。希望本文方法能夠給對(duì)本文感興趣的讀者以一定的啟發(fā)和幫助。
本文提出的軟件組件的另一個(gè)主要問(wèn)題是該組件的適用領(lǐng)域問(wèn)題。表面上看起來(lái),本文提出的軟件組件似乎僅適用于車(chē)輛分布和車(chē)輛調(diào)度。但本文方法仍然可以應(yīng)用到那些場(chǎng)地相關(guān)性較強(qiáng)的大型倉(cāng)儲(chǔ)管理領(lǐng)域或物流領(lǐng)域[10,11],如集裝箱貨場(chǎng)裝卸管理、智能存車(chē)場(chǎng)管理等多個(gè)應(yīng)用領(lǐng)域。隨著社會(huì)的發(fā)展和科技的不斷進(jìn)步,本文提出的組件和設(shè)計(jì)思想仍然會(huì)有較大的適用空間。
[1]Juval Lowy..NET component programming [M].USA:O’Reilly Media Inc,2005.
[2]CHEN Honglong,LI Renfa,LI Rui.A high dependable com-ponent assignment method in selfadaptive software based on architecture[J].Journal of Chinese Computer System,2012,33 (6):1153-1158 (in Chinese).[陳洪龍,李仁發(fā),李蕊.一種面向體系結(jié)構(gòu)自適應(yīng)軟件中的高可靠性組件分派方法[J].小型微型計(jì)算機(jī)系統(tǒng),2012,33 (6):1153-1158.]
[3]YAN Song.Study on loosely-coupled component communication paradigm [J].Computer Engineering and Design,2012,33 (3):991-997 (in Chinese).[嚴(yán)勇.松耦合組件的通信模式研究 [J].計(jì)算機(jī)工程與設(shè)計(jì),2012,33 (3):991-997.]
[4]GE Xinmao,SHEN Changxiang.Method for layering components towards structured protection [J].Computer Engineering and Application,2011,47 (36):25-28 (in Chinese).[蓋新貌,沈昌祥.一種面向結(jié)構(gòu)化保護(hù)的組件層次劃分方法[J].計(jì)算機(jī)工程與應(yīng)用,2011,47 (36):25-28.]
[5]ZHANG Li.Application of paging component based on modelview-controller pattern [J].Computer Application,2011,37(21):255-257 (in Chinese).[張俐.基于 MVC模式的分頁(yè)組件應(yīng)用 [J].計(jì)算機(jī)工程,2011,37 (21):255-257.]
[6]GAO Siwei,ZHANG Dianye.A study on improving adaptability of shunting system model[J].Journal of Transportation Systems Engineering and Information Technology,2003,3(1):84-88 (in Chinese).[高四維,張殿業(yè).提高調(diào)車(chē)作業(yè)指揮模型系統(tǒng)適應(yīng)性的研究 [J].交通運(yùn)輸系統(tǒng)工程與信息,2003,3 (1):84-88.]
[7]WANG Yalin,ZHOU Ying.Shunting trip plan assistant making system based on MVC [J].Computer Engineering,2010,36 (21):257-259(in Chinese).[王雅琳,周穎.基于MVC的調(diào)車(chē)作業(yè)計(jì)劃輔助編制系統(tǒng) [J].計(jì)算機(jī)工程,2010,36 (21):257-259.]
[8]SUN Xuebo,WANG Zhu.A general software design approach based on layered meta data [J].Computer Application and Software,2008,25 (11):112-114 (in Chinese).[孫學(xué)波,王姝.基于元數(shù)據(jù)的通用軟件設(shè)計(jì)方法 [J].計(jì)算機(jī)應(yīng)用與軟件,2008,25 (11):112-114.]
[9]WANG Siming,MA Zili,CHEN Yongyi.A model of multiple queues system with double cyclic mobile service[J].Journal of Lanzhou University (Natural Science),1991,27 (4):10-18 (in Chinese).[王思明,馬自立,陳永義.多隊(duì)列雙向循環(huán)移動(dòng)服務(wù)系統(tǒng)的研究 [J].蘭州大學(xué)學(xué)報(bào) (自然科學(xué)版),1991,27 (4):10-18.]
[10]ZHENG Rong,DONG Shaohua.Inventory information visual management system in plane warehouse [J].Logistics Technology,2006 (3):194-196 (in Chinese).[鄭榮,董紹華.平面?zhèn)}庫(kù)庫(kù)存信息可視化管理系統(tǒng)的研究 [J].物流技術(shù),2006 (3):194-196.]
[11]CAO Langcai,LUO Jian.Visualization system design and storage location optimization of AS/RS [J].Journal of Xiamen University,2012,51 (1):48-50 (in Chinese).[曹浪財(cái),羅鍵.可視化自動(dòng)倉(cāng)儲(chǔ)系統(tǒng)設(shè)計(jì)與貨位優(yōu)化 [J].廈門(mén)大學(xué)學(xué)報(bào) (自然科學(xué)版),2012,51 (1):48-50.]