?

分布式鐵路車輛分布組件的設計與實現

2014-11-30 07:48孫學波李昕妍
計算機工程與設計 2014年1期
關鍵詞:列表隊列雙向

孫學波,李昕妍

(遼寧科技大學 軟件學院,遼寧 鞍山114051)

0 引 言

目前,應用組件開發應用軟件已經成為主流的軟件開發方法[1]。當前流行的各種軟件開發架構體系,如 Microsoft Visual Studio.Net和Eclipse等,均提供了大量的可復用的軟件組件,以支持各種應用軟件的開發。應用現有組件不僅可以有效地降低軟件開發的難度,而且也有利于提高軟件開發的效率和質量。這些軟件組件基本能夠滿足大部分應用領域的功能需求,如基于數據庫的管理信息系統領域等。但對于某些特殊的應用領域,卻無法找到合適的軟件組件來滿足這些特殊的需求。因此,獨自開發滿足這些特殊需求的可復用的軟件組件就成為一件十分有意義的事了[2-5]。

在鐵路運輸管理系統[6-8]項目中,我們遇到了一個需要提供車輛分布的可視化表示和交互式地進行車輛調度作業的特殊需求。為更好地支持這一需求,我們提出了一個基于多隊列[9]的分布式鐵路車輛分布可視組件的概念,并給出了其具體的設計與實現。應用這個組件成功地解決了項目中的車輛分布的可視化問題和車輛調度作業問題。

1 基本概念

為完整地描述組件的邏輯結構,首先給出與本組件相關的一些基本概念。

隊列元素:本文中的隊列元素是指一個實現了某個特定接口的實體對象,用于描述現實世界中的某個客觀實體。在應用實例中,用于表示鐵路車輛實體。隊列元素所在的隊列為其所處的某種”環境”,其特殊性在于元素與其所處的環境之間存在某種順序和位置上的關聯或約束。

本文強調以下兩種約束:

(1)位置約束:每一個隊列元素在其所在的隊列中均具有一個位置屬性,這個位置不一定決定于元素本身的屬性,它可能更多地決定于人對與隊列元素對應的客觀實體的管理 (如車輛在股道上的位置或貨物在貨位上的位置)。顯然這個屬性是可以并且需要被改變的。

(2)接口約束:為實現對隊列元素實施有效的管理,就需要在組件內部對隊列元素定義一系列操作,同時又希望這些操作與隊列元素實體的具體屬性無關。因此本組件僅為隊列元素定義了一個抽象類,從而省掉了其對應實體類的具體實現,其具體實現則留到其具體的應用中。

隊列:所謂隊列是一個由隊列元素構成的線性表,其插入操作限制在表的一端進行,而刪除則限制在表的另一端進行。隊列的操作則包括初始化、進隊、出隊、判斷隊列是否空、取隊列元素和隊列的可視化等。

雙向隊列:所謂雙向對列是一個由隊列元素組成的線性表。其插入和刪除操作則限制在隊列的兩端進行。雙向隊列的操作與隊列操作基本相同,不同的是僅僅放寬了對插入和刪除位置的限制。一個雙向隊列用于表示現實世界中的某個實體或實體集,如在本項目案例中,表示一條“股道”。顯然,雙向隊列僅是對隊列概念的一個擴充。

多重雙向隊列[9]:所謂的多重雙向隊列是一個由若干個雙向隊列組合而成的一個集合。也可以說多重雙向隊列是一組實現了某個特定接口的對象構成的集合,這些對象分布在若干個雙向隊列中,而所謂的多重雙向隊列就是由這樣一組多重雙向隊列聚合而成的一個對象。

多重雙向隊列的實質是一組由多個雙向隊列構成的集合,它對應于現實世界中的某個特定的實體或實體集。如果一個隊列表示某調車場里面的一條股道,那么,這個隊列則對應了一個實體集 (一組車輛),它也對應了一個特定的實體股道。而一個隊列集合則可以表示一個或多個調車場 (此時也可以稱為作業區)。此時則更容易理解,多重雙向隊列概念所具有的現實意義。

多重雙向隊列從概念上來說是一組雙向隊列構成的集合,它實際上是現實世界中一組邏輯相關的有序元素集合構成的集合。元素在某個隊列中的相對位置則描述了元素與元素、元素與隊列以及元素與多重雙向隊列之間的相對關系。

所以,多重雙向隊列上的操作就應該是以特定方式描述、展現和維護它們之間的關系的一組操作集合。

本組件定義的多重雙向隊列的主要操作如下:

(1)初始化:初始化多重雙向隊列,計算每個雙向隊列的大小、顯示位置等數據。初始化每個雙向隊列對象。

(2)可視化:顯示每一個雙重隊列的可視屬性及其隊列中的元素。

(3)修改隊列元素:用于修改指定元素的實體屬性。

(4)生成隊列操作命令列表:與用戶交互編制用于在不同隊列間轉移元素的 “隊列操作命令列表”。

(5)執行隊列操作命令列表:執行當前的隊列操作命令列表,修改隊列元素位置。

多重隊列操作:首先,把某個雙向隊列的一個入隊或出隊操作稱作一個隊列操作命令。其次,把一組邏輯上相關的隊列操作命令稱為一個多重隊列操作。顯然,一個多重隊列操作實際上就是車輛調度系統中的一個調車作業計劃,它可用于實施一次車輛調度作業。

例如要將第三個隊列中的第3個元素開始的10個元素移動到第五個隊列的第3個元素和第4個元素之間。它所需要的多重隊列操作的內容見表1。

表1 多重隊列操作示例

2 組件的基本結構

2.1 基本的組件類

組件類 (MQComponent):在.NET架構下,組件被定義為一個Usercontrol類的派生類對象,它負責提供組件的外部接口,由一組預先定義好的一組屬性、操作和事件組成。

組件的用戶界面類 (GrahicsUserInterface):組件的應用程序界面,用于實現多重雙向隊列的可視化表示,整個界面由3個可視的Panel對象元素組成,分別用于實現每個隊列、每個隊列的隊列元素以及隊列元素的順序的可視化表示。

圖1 給出了組件的用戶界面的結構,其中Queue panel用于顯示多重隊列 (即車輛場地)的結構,Queue Element Panel負責顯示隊列元素,即車輛。其具體實例可參見圖。

圖1 組件的界面結構

多重隊列類 (MultiQueue):作為用戶多重雙向隊列類的基類,定義了用戶多重雙向隊列類的接口,是本組件的核心類。在結構中作為組件對象的一個組成對象,表示組件中最高層次的隊列元素集合。

雙向隊列類 (Bidirectional Queue):作為用戶雙向隊列類的基類,定義了用戶雙向隊列類的接口,是多重雙向隊列對象的組成對象,表示一個用戶隊列元素的集合。

隊列元素類 (QueueElement):作為用戶隊列元素類的基類,定義了組件所需的隊列元素類的接口,是組件中最基本的組成元素對象,也是組件各種操作的最基本的單位元素。

多重隊列操作類 (OperationList);由一組隊列操作命令組成的列表,用于改變組件中指定隊列的指定元素的位置。

2.2 組件類之間的關系

圖2 給出了組件中定義的主要類和它們之間的關系,其中Usercontrol類是一個.net組件類,用于定義一個封裝相關的現有控件并提供其自身邏輯的新控件提供基類。

圖2 組件中各個類之間的關系

MQComponent是Usercontrol類[1]的派生類,用于實現本組件自身的業務邏輯。GraphicsUserInterface類是本組件的用戶界面類,用于實現本組件中多重雙向隊列的可視化和與用戶的交互操作。

MultiQueue,Bidirectional Queue和 QueueElement是本組件自定義的3個類,分別表示本組件的多重雙向隊列類、雙向隊列類和隊列元素類。

MultiQueueCommandList、MultiQueueCommand、PictureOfCommand為命令列表類和命令類和命令圖形類,用于管理隊列操作命令列表,定義了組件的主要操作。

最后的兩個類 MoveCommandList、MoveCommand是組件提供給用戶的操作列表類。也是組件的一個外部接口。

2.3 組件的外部接口

為了擴展組件的適用范圍,本組件以基類的形式對外提供了一組外部接口。用戶可通過繼承和覆蓋的方式使用這些接口使其業務邏輯與組件提供的服務進行有效的結合。

本組件提供的接口包括如下3種:

(1)接口是組件在運行時與終端用戶 (操作員)交互所需的操作員接口。這個接口由一組圖形化交互操作組成,包括查看和修改隊列元素的屬性、刪除隊列元素、選擇隊列元素、改變隊列元素位置等操作。

(2)接口是組件在運行時與客戶程序交互所需的動態接口。這個接口主要由組件類定義的一組屬性、方法和事件組成。

(3)接口開發客戶程序時組件與客戶程序員交互所需要的靜態接口,這個接口由一組組件對外公開的類組成。開發客戶程序時客戶可以通過繼承的方式使用這個接口。

客戶程序接口:運行時與客戶程序交互的動態接口主要通過在組件類 (MQComponent)中定義的一組屬性、方法和事件來實現。其基本的屬性、方法和事件概要敘述如下。

組件主要屬性包括:隊列元素的顯示寬度、高度、字體、字號、顏色、線型、線寬和對齊方式等屬性。表示隊列元素屬性和狀態的圖像列表等屬性。

組件類的方法包括:初始化、添加多重雙向隊列。

組件的主要方法見表2。

表2 組件的主要方法

組件類的主要事件見表3。

表3 組件的主要事件

程序員接口:設計時與客戶程序員交互所需要的靜態接口主要由組件提供的若干個基類組成,這些類可以作為用戶程序的某些類的基類。

這些類主要包括多重雙向隊列類 (MultiQueue)、雙向隊列類 (Bidirectional Queue)、隊 列元素 類 (QueueEle-ment)和操作列表類 (OperationList)。這些類的基本定義如下:

多重隊列類MultiQueue:在多重隊列類MultiQueue的設計中,參照了GOF設計模式中的組合模式,使得組件實例中可以包含多個多重雙向隊列,使得組件實際上包含了一個多重雙向隊列集合。

圖3 所示的類圖中,ID、Name為多重隊列的標識符和名稱屬性;left,top,width和height等為多重隊列的顯示屬性,其值組件的初始化算法自動生成;pQueue為某個雙向對列的引用,表示多重隊列中的隊列集合;屬性next是某個多重隊列的引用,表示一個組件實例中的多重隊列可以是一個復合對象。Draw(Grahpics g)是一個虛方法,用于顯示多隊列的名稱等屬性;AddQueue(BiQueue q)方法用于向多重隊列中添加一個雙向對象;SelectElement(Crectangle rect)和UnSelectElement()方法用于實現交互式地選擇隊列元素。

雙向隊列類BiQueue:雙向隊列類則相對簡單,主要封裝了雙向類的基本操作,包括入隊、出隊、顯示、選擇等操作??蛻舫绦蚩梢砸岳^承這個類的方式使用該組件。其基本定義如下:

圖3 多重隊列類類圖

圖4 所示的類圖中,ID、Name為隊列的標識符和名稱屬性;left,top,width和height等為隊列的顯示屬性;Next是某個雙向隊列的引用,用于鏈接多重隊列中的雙向隊列。Biqueue(string ID,string Name)為雙向隊列類的構造函數;Draw(Grahpics g)用于顯示隊列的名稱等屬性;EnterQueue(QueueElement e,int direction)和DeleteQueue(int direction)方法用于添加和刪除隊列元素;Select(CRectangle rect)和UnSelect()方法用于交互式地選擇隊列元素;CalculateLayout()用于計算隊列元素的顯示位置。

圖4 雙向隊列類類圖

隊列元素類QueueElement:隊列元素為一個抽象類,用于表示具體業務邏輯所需要的實體類??蛻舫绦虮仨毨^承這個類。具體設計如圖5所示。圖中,屬性ID、Name為隊列元素的標識符和名稱;IsSelected和IsModified為兩個標志,用于標記隊列元素的被選中和被修改等狀態。該類的方法中,Select和UnSelect用于選擇隊列元素,IsSelected()和IsModified()用于返回該隊列元素的選擇狀態和修改狀態;Draw(Graphics g)、Modify()和Display()等方法均設計為虛函數,用戶可以在派生類中覆蓋它們。Draw(Graphics g)方法用于顯示隊列元素的名稱和ID,Modify()和Display()方法是兩個純虛函數,這兩個函數允許用戶在派生類中實現它們,以便用戶以自己的方式顯示和修改隊列元素的屬性。

圖5 隊列元素類類圖

隊列操作命令列表類 (MoveCommandlist):隊列操作命令列表類封裝了一組隊列操作命令,用于通知用戶多重雙向隊列內部元素位置變化所需要的操作命令細節,實際應用中這個操作列表可能會被傳遞到現場或某中自動化設備,完成對隊列元素實體的實際操作,改變實體元素的位置。組件內部也用于更新組件中指定元素的當前位置。

隊列操作命令數據結構見表4。

命令列表類可以用一個簡單的由上述隊列操作命令數據結構組成的線性表來實現。特別要注意的是生成過程中要校驗每一條命令的正確性和整個命令列表的正確性問題。

表4 隊列操作命令數據結構

3 組件的實現

3.1 多重雙向隊列組件的初始化

這個算法根據導入到多重雙向隊列中的雙向隊列的個數和層次結構以及隊列容量計算每個隊列的大小和位置。為隊列的可視化過程做準備。

此算法由組件中的 MultiQueueComponent、MultiQueue和BiQueue這3種類型的對象協同實現。3種對象間的協作關系如圖6所示。

圖6 多重雙向隊列組件的初始化過程

多重雙向隊列組件初始化的算法由分布在各個類中的多個操作實現。初始化算法的實現由組件類MultiQueue-Component、多重雙向隊列類 MultiQueue和雙向隊列類BiQueue的同名操作CalculateLaout協作完成。具體實現如下。

算法一:多重雙向隊列組件的初始化

void MultiQueueComponent::CalculateLaout()

1計算并設置每個界面元素的顯示位置

2計算組件界面的顯示位置。

MultiQueue*p=mMultiQueue;

int left=0;

//設置組件中每一個多重雙向隊列的顯示位置

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;//多重雙向隊列的

for(p=mBDQueue;p?。絥ull;p=p.next)

//設置多重雙向隊列中每一個雙向隊列的顯示位置

left=p->CalculateLaout(left);

w=w+EWidth;

Width=w;Height=mComponent.EHeight;

return left;//返回下個多重雙向隊列的左邊界

int BiQueue::CalculateLaout(int left)

//設置隊列標題的顯示位置

Top=0;Left=left;Width=EWidth;Height=EHeight;

for(int i=0,top=0;i<LengthOfQueue;i++)

//設置每個隊列元素的顯示位置

Rect [i]=new Rectangle(left,top,EWidth,EHeight);

top=top+EHeight;

return left+Width;//返回下個隊列的左邊界

其它算法的實現與此算法類似,不再給出細節。

3.2 多重雙向隊列組件的可視化

多重雙向隊列的可視化過程負責根據初始化的計算結果實現組件中各個可視元素包括多重雙向隊列、每個雙向隊列和隊列中每個隊列元素的可視化??梢暬^程如圖7所示。

圖7 多重雙向隊列組件的可視化過程

多重雙向隊列組件的可視化結果可參見圖7,圖中第一行顯示實例中每個多重雙向隊列,第二行則列出了每個多重雙向隊列的子隊列。組件中每一列表示一個雙向隊列,每個隊列中的每個單元格表示一個隊列元素,空白的單元格表示該位置空。

3.3 隊列操作命令的可視化生成

組件中,隊列操作命令列表的使用過程被分成3個步驟進行:首先,是隊列操作命令列表的編制過程。其次,輸出生成的隊列操作命令列表。在組件外部根據生成的隊列操作命令列表完成隊列元素對應實體的位置的改變。最后,組件再依據實體的實際位置改變組件內部隊列元素的位置。

本組件提供了兩種隊列操作命令列表的生成方法。一種是使用對話框由用戶人工編制的生成方法。另一種是基于圖形的交互式生成方法。這兩種方法各有優缺點,可以供用戶選擇使用。但后一種方法是一種自然的工作方法,更符合用戶的日常工作習慣。它們使用戶可以應用組件提供的功能生成用戶所需要的隊列操作命令列表,從而幫助用戶完成用戶所需要的隊列元素重排任務。由于篇幅限制,下面僅給出基于圖形的生成方法。

(1)隊列操作命令的可視化:組件中,為了表達用戶對隊列元素的操作意圖,組件定義了一個規則的圖形,來表示一個對指定的隊列元素要進行的隊列操作。這樣,一個完整的隊列操作命令列表就可以用一組這樣的隊列操作圖形來直觀地加以描述。而按照進出隊列的位置不同,組件定義了4種形狀不同的圖形表示。

一個隊列操作圖形一個矩形和一個由六條直線段和兩條Bezier曲線封閉而成的一個路徑組成。矩形區域標識了被選定的隊列元素,路徑的控制點由組件使用橡皮筋技術在與用戶的交互過程中動態生成,路徑中貝塞爾曲線兩端的一階曲率則直觀地標記了隊列操作的方向,箭頭端點指定了元素要移入的隊列。根據雙向隊列的定義,容易知道一個隊列操作圖形可能有4種不同的基本形狀。

具體圖例如圖8所示。圖中每個圖例的含義是非常直觀的。如圖8中的圖例1表示按向上方向取出4個元素按向下方向放入箭頭指向的隊列。圖例3表示按向下方向取出4個元素按向下方向放入箭頭指向的隊列。

圖8 隊列操作命令的圖形表示

另外,一個隊列操作命令圖形也可以包含多組不同的隊列元素。如圖9所示。

圖9 隊列操作命令圖圖示

組件中,隊列操作命令圖形由PictureOfCommand類實現,它與其它類的關系見圖2。

(2)多重隊列操作的交互式生成:這樣,任何一個對隊列元素位置改變的意圖 (隊列操作命令)就可以由一組既定的隊列元素操作圖形來加以描述,所以這就使得用戶可以通過創建一組這樣的隊列元素圖形來實現其要對隊列元素位置的修改。組件內部還實現了根據一組圖示生成和導出與之等價的隊列操作命令列表的功能,該功能以激活一個特定事件的方式將這個操作列表傳遞給客戶程序。

圖9 給出了一個完整的隊列操作命令圖形。圖10給出了圖9中隊列操作命令的執行結果。表5給出了圖9中隊列操作命令導出的對列操作列表。

另外,根據這個隊列操作命令列表修改相應隊列元素位置的算法顯然是很容易實現的。

圖10 隊列操作命令的執行結果

表5 生成的調車作業計劃

4 組件的應用實例

在實際的鐵路運輸系統開發項目中,應用本組件成功的構建了一個車輛分布和車輛調度操作的分布式可視化操作平臺,并以這個平臺為基礎實現了幾乎所有車輛調度作業的可視化操作,同時以此平臺為基礎構建了該項目的整體架構,實現了車輛調度和管理的數字化[4]。

圖11 基于組件的鐵路運輸系統的體系結構

圖11 給出了基于組件的鐵路運輸系統的體系結構,該體系結構運用了本文描述的軟件組件,圖中的 “車輛分布組件”就是本文描述的車輛分布組件的一個應用實例。

這個組件與結構中其它各組件相互協作構了一個完整的分布式鐵路運輸管理系統。

圖12 給出了鐵路運輸管理系統項目中的一個組件應用實例,它表示了某作業區某一時刻的車輛分布情況。

在該應用中,每一個組件實例被映射為某一個作業區,一個多重雙向隊列被映射為一個車場,一個雙向隊列被映射為一條股道,而一個隊列元素則被映射為一個車輛。而一個組件實例上的一個隊列操作命令列表實例則被映射為一個作業區上一次車輛調度作業的調車作業計劃。系統中所有組件實例構成了整個系統的一個完整的車輛分布的可視化分布和調度平臺。項目中該組件的各個實例與項目中其它類型的組件相互配合則構成了整個鐵路系統中完整的車輛分布模型,從而實現了整個系統中車輛的實時的和精確的管理。

圖12 車輛分布組件應用實例

5 結束語

由于篇幅關系,本文僅概括性地給出本組件的主要設計思路和實現方法而忽略了很多技術細節。

本文所述的方法是從實際案例中提煉總結出來的,在實際項目中,這個方法有效地解決了項目中面臨的諸如軟件通用性等多方面的技術難題,提高了項目的開發效率和質量,同時也極大地降低了軟件開發的成本。希望本文方法能夠給對本文感興趣的讀者以一定的啟發和幫助。

本文提出的軟件組件的另一個主要問題是該組件的適用領域問題。表面上看起來,本文提出的軟件組件似乎僅適用于車輛分布和車輛調度。但本文方法仍然可以應用到那些場地相關性較強的大型倉儲管理領域或物流領域[10,11],如集裝箱貨場裝卸管理、智能存車場管理等多個應用領域。隨著社會的發展和科技的不斷進步,本文提出的組件和設計思想仍然會有較大的適用空間。

[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).[陳洪龍,李仁發,李蕊.一種面向體系結構自適應軟件中的高可靠性組件分派方法[J].小型微型計算機系統,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).[嚴勇.松耦合組件的通信模式研究 [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).[蓋新貌,沈昌祥.一種面向結構化保護的組件層次劃分方法[J].計算機工程與應用,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模式的分頁組件應用 [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).[高四維,張殿業.提高調車作業指揮模型系統適應性的研究 [J].交通運輸系統工程與信息,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的調車作業計劃輔助編制系統 [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).[孫學波,王姝.基于元數據的通用軟件設計方法 [J].計算機應用與軟件,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).[王思明,馬自立,陳永義.多隊列雙向循環移動服務系統的研究 [J].蘭州大學學報 (自然科學版),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).[鄭榮,董紹華.平面倉庫庫存信息可視化管理系統的研究 [J].物流技術,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).[曹浪財,羅鍵.可視化自動倉儲系統設計與貨位優化 [J].廈門大學學報 (自然科學版),2012,51 (1):48-50.]

猜你喜歡
列表隊列雙向
雙向度的成長與自我實現
降低寄遞成本需雙向發力
用“雙向宮排除法”解四宮數獨
學習運用列表法
擴列吧
隊列里的小秘密
基于多隊列切換的SDN擁塞控制*
在隊列里
豐田加速駛入自動駕駛隊列
一種軟開關的交錯并聯Buck/Boost雙向DC/DC變換器
91香蕉高清国产线观看免费-97夜夜澡人人爽人人喊a-99久久久无码国产精品9-国产亚洲日韩欧美综合