論如何從零開始攻略乙個ADT ADT整體設計篇

2022-09-09 03:39:11 字數 2445 閱讀 1664

一些自己在做lab開發adt時的經驗和體會。

本文主要介紹如何根據需求,來決定要設計哪些adt,以及如何處理不同adt之間的包含關係。

1.adt的選取

如果甲方已經規定了需要實現哪些adt,那自然是墜吼的。

如果沒有,首先我們需要分析甲方的需求,然後提取出其中有價值的實詞

以某實驗為例:

棋類遊戲由乙個棋盤、一組棋子組成,雙方交替在棋盤上走棋。

乙個尺寸為 n*n 的棋盤:其中 n 表示每一行/每一列的格仔數。

棋盤上共有 n*n 個格仔和(n+1)*(n+1)個交叉點

一組棋子:每個棋子屬於乙個特定的種類,不同的棋類遊戲中包含的棋子種類不同。

在一盤棋局中,不同種類的棋子的數量不同。

在遊戲進行過程中,需要區分棋子是屬於遊戲中的哪一方玩家

要求的實詞已用粗體標出,最簡單粗暴的方法,就是對每個實詞,都設計乙個adt與之對應

這樣的好處是無腦,維護起來方便,而且可擴充套件性強:除非甲方一拍腦袋決定在專案中新創造乙個概念,不然操作都是基於已有的概念。

麻煩就是adt的巢狀的深度會很大,而且在後面考慮不同adt之間關係的時候會很麻煩。

一種方法是根據經驗,來去掉不必要的adt,例如上例中的尺寸、種類、數量。

由於j**a本身對物件豐富的支援,大多數操作完全可以靠已有的方法來實現,像是尺寸、數量這種單純的integer,或者種類這種單純的string,而且這些adt在將來的應用中,擴充套件的可能性並不大。

假如說這些adt並不「單純」:例如乙個種類實際上由乙個字串和乙個整型編碼構成,或者將來可能會有擴充套件:例如玩家這個adt,將來可能會包含擁有的棋子種類之類的資訊,那麼就不建議省略掉了。

此外,像是種類這個屬性,在j**a裡可以省略成乙個string,但在c裡,還是老老實實地去寫個struct吧。

另一種方法是合併實現上類似的adt,例如玩家和棋子,它倆在需求中都是只有乙個sting型的label/name,但是又由於將來可能的擴充套件,而不便於去掉。

因此我們可以定義乙個item類,裡面僅有乙個string型的label,然後將玩家和棋子都宣告成item類。

當然這樣也有不少麻煩,比如未來不便於特化擴充套件——這一點可以用繼承來克服——以及由於item類裡的方法命名都比較一般化,很容易在實現的時候亂套:player.getlabel()是指玩家的名字還是玩家的編號,還是別的什麼?

所以我個人感覺比起在第一次編寫的時候就進行合併,還是在將來用到的時候想起來,以前寫過乙個類似的比較合適。

2.adt的關係

這裡主要討論字面意義上的「屬於」這層關係的處理。

顯然棋盤和玩家兩者之間是沒有關係的:玩家不屬於棋盤、棋盤也不屬於玩家。所以這兩個可以大大方方地視作並列。

而對於遊戲、玩家、棋子、座標這四者,直覺上認為是遞進的包含關係,座標∈棋子∈玩家∈遊戲。但去分析一下需要實現的操作,就發現這樣是不合適的:我們需要根據跟定地座標,來確定在這裡的棋子;需要根據棋子,來確定它屬於哪個玩家。

當然我們可以大大咧咧地去把所有棋子遍歷一邊,來找出哪個棋子的座標是給定的座標。這種方法好在直觀,壞處也是一堆,就不在此贅述了。

從上述討論可以看出,問題在於我們的檢索並不是單向的,而是雙向的,所以雖然直覺上它們是屬於關係,但在操作上,它們的地位是對等的。

所以有一種解決方案是:完全拋棄屬於的概念,而將二者並列。也就是說,⊆遊戲,但是座標、棋子、玩家三者並列。

但沒有了屬於這層關係,我們怎麼確定誰跟誰對應?

方法很簡單:我們用map對映表來記錄這個對應關係,由於map中實現了鍵值互查的方法,所以我們可以很方便地進行雙向檢索。

以下述**為例:

public

class

game

可以看到,棋盤、棋子、玩家、位置是並列關係,而棋子和玩家的對應關係記錄在belong中。

棋子和位置的關係我記錄在了board的乙個子map中,為了體現這種對應關係是在棋盤上的。

而由於我們並不需要實現:確定某個玩家是在哪個遊戲裡,或者某個棋子是在哪個遊戲裡這種操作,所以我讓棋盤、棋子、玩家、位置都屬於game這個類。

現在看來,這種關係可以進一步「真實化」。

例如,positions應該放在board當中:我們並不需要根據位置確定棋盤;棋子和位置依然是一定程度上的並列關係;這樣看起來更真實。

此外,這兩種方法在效率上應該是一致的,因此第二種方法更像是增大空間開銷,來減少方法的設計,從而減少潛在的bug。

IntelliJ IDEA 從零開始建立乙個專案

1 如果intellij idea中當前沒有開啟的專案,單擊歡迎介面上的建立新專案。否則,選擇 然後會開啟新建專案嚮導視窗 2 在嚮導的第一頁,在左側窗格中,選擇專案類別。這可能是你要使用的技術,專案的目標平台或執行時等。在頁面的右側部分以及後續步驟中的設定取決於所選專案類別。對於相應的說明,請參閱...

IntelliJ IDEA 從零開始建立乙個專案

1 如果intellij idea中當前沒有開啟的專案,單擊歡迎介面上的建立新專案。否則,選擇 然後會開啟新建專案嚮導視窗 2 在嚮導的第一頁,在左側窗格中,選擇專案類別。這可能是你要使用的技術,專案的目標平台或執行時等。在頁面的右側部分以及後續步驟中的設定取決於所選專案類別。對於相應的說明,請參閱...

IntelliJ IDEA 從零開始建立乙個專案

1 如果intellij idea中當前沒有開啟的專案,單擊歡迎介面上的建立新專案。否則,選擇 然後會開啟新建專案嚮導視窗 2 在嚮導的第一頁,在左側窗格中,選擇專案類別。這可能是你要使用的技術,專案的目標平台或執行時等。在頁面的右側部分以及後續步驟中的設定取決於所選專案類別。對於相應的說明,請參閱...