2011-06-03 111 views
3

我只是想了解一個面向對象的概念,這聽起來很瑣碎,但我不知道爲什麼我覺得它很混亂。對象關係設計

無論如何,我想,例如,如果我有一個動物類和位置類。我只允許一隻動物隨時在一個地方。所以它就像是一對一的關係。同時,我希望Animal和Location類不需要某種雙向引用,以便它們保持鬆散耦合。如果說我有這個:

class Animal { 
    private Location loc; 

    public Animal(int x, int y) { 
     loc = new Location(x,y); 
    } 

    public static newAnimal(Location[][] map, int x, int y) { 
     if(map[x][y] != null) { 
     return new Animal(x, y); 
     } else return null; 
} 

class Location extends Point { 
    public Location(int x, int y) { 
     super(x, y); 
    } 
} 

public static void main(String[] args) { 
    //populates a map 
    Location[][] map = new Location[10][10]; 
    for(int x=0; x<10; x++) { 
     for(int y=0; y<10; y++) { 
     map[x][y] = new Location(x, y); 
     } 
    } 

    Animal dog = new Animal(2, 4); //dog is at location 2,4 
    Animal cat = new Animal(5, 6); //cat is at location 5,6 

    //But this does not restrict a constraint requirement that there should only be one animal at any one point 
    Animal horse = new Animal(2, 4); //now, horse is at the same location as dog but we only wanted one location to have one animal 

    Animal rabbit = Animal.newAnimal(map, 20, 50); //rabbit is null because it is out of the map size 
} 

從這裏,我預見到2個問題。

首先,因爲我的位置不知道動物是否已經在它上面,所以許多動物都可以指向地圖陣列上的相同位置。這會違反我想要的1-1多重約束。就我而言,我讓動物擁有這個位置。這可能是這種情況發生的原因。如果說我讓位置擁有動物,這可以解決。但是如果我想知道我的動物在哪裏,我需要遍歷整個地圖才能找到我的動物的位置在哪裏?或者,我可以保留一個雙向引用,但這會導致類被高度耦合。

我覺得可能是一個問題的第二個問題是Animal類中的設計。我有一個靜態的newAnimal()方法來實例化新的動物。我這樣做是因爲我認爲允許調用者直接從構造函數創建新的Animal實例可能會允許超出範圍的座標輸入。但我仍然覺得設計非常尷尬。

我在示例中使用了Java代碼。我認爲類內的設計本身並不涉及數據庫。

改善我提出的兩個問題的任何建議都可能很好。 謝謝!

+0

一棵樹不包含猴子,而猴子也知道他在哪一棵樹,甚至可能如何計算猴子時尚之後剩下多少香蕉? – Affe 2011-06-03 06:57:41

+0

@Affe,感謝您添加評論。我仍然有點困惑。你能再詳細一點嗎?謝謝! – Carven 2011-06-03 07:14:19

+0

這是我的方式來說,如果您的業務/應用程序域包含兩個共享狀態的事物,它們在定義上是耦合的。如果試圖模仿他們,那麼跳過籃球有什麼好處呢? – Affe 2011-06-03 07:19:11

回答

2
1.Location/Map in our case is a real world object and has boundaries. 
2.Map can not hold more than one animal at any pont 
3.An animal can not occupy more than one location 

以上是相關的問題的事實。

位置可以被視爲矩陣。一個二維數組。 目前我們假設一隻動物只能保持一個單位(一個單元),並且不會少於或超過給定時間點的數量。

This 二維數組是動物(它可以包含Animal對象),然後遏制是真實的,沒有兩個可以佔據相同的空間 - 它必須替換現有的空間。

此外,動物的位置屬性應該更新。

另外,A LocationManagerClass可以寫入存儲和管理動物在地圖上的佔用。但是,如果它接近「空間佔用」的真實生活場景,那麼它會被進一步拉高。

+0

這是一個不錯的主意!但在二維陣列中,動物種植到處都是。但是當我需要知道特定動物的位置時,我必須遍歷整個2D陣列才能找到它的當前位置。這會花費太多而無法找到它的當前位置嗎?更重要的是,如果地圖變大,環路也會變得更重。 – Carven 2011-06-03 14:16:53

+2

你可以保留一個動物/位置的字典,它保持每個動物的位置......然後你將有一個O(1)訪問它的位置。 – 2011-06-04 15:48:28

+0

@xEnOn,是的,你是完全正確的,這將是昂貴的。這就是爲什麼我建議「另外,動物的位置屬性應該更新。」在現實世界中,如果我佔據一個空間,並且如果有人需要找到我所在的位置,那麼他需要搜索整個地圖 - 別無他法。但我們並不經常喜歡這樣 - 所以我們有技巧 - 就像我們說「我只是在你後面」,我在家裏「等等(我擁有知識),如果我沒有在沙漠中的知識,我會說」我迷路了「,然後找到我很難找到我,所以總是把好位置信息給Anima對象:) – WinW 2011-06-06 12:01:47

1

我會有單獨的界面+類來管理/維護關係,並有方法添加新的動物或將動物移動到其他位置。通過這種方式,您可以輕鬆檢查並維護您的前/後條件。此外,我會保持Animal和Location不變(在這種情況下)。 有接口和類會更容易做關係的不同實現:地圖,數據庫,文件等

0

爲什麼要讓Animal類包含位置?

另一種方法是在Animal類中只有Animal屬性。位置類很好,因爲它是。有一個叫Map的第三課,它將管理位置(在地圖上)和動物在每個位置。

一個C++這個代碼將是這樣的:

class Animal 
{ 
    public: 

      Animal(char *name); 
      ~Animal(); 

      char *getName(); 
    private: 

      char *name; 

};

//這裏我沒有使用Location類,而是使用x,y。你可以做出這麼小的改變。

class Map 
{ 

    private: 

     Animal *animalLocation[10][10]; 


    public: 
     //Note this function will check if any Animal exists at the specified (x,y). 
     void addAnimal(int x, int y, void *animal); 
     void* getAnimal(int x, int y); 

     Map(); 
     ~Map(); 

};

+0

這也是一個很好的方法!但是隻有一件事,如果我想知道某個特定動物的位置,我仍然需要遍歷整個地圖數組以找出它的位置,對嗎?無論我使用什麼樣的設計,這都是我無法逃脫的東西嗎?當然,在位置和地圖之間有雙向關係動物可以避免這個循環,但我不知道哪個是更值得的。 – Carven 2011-06-04 14:49:23

+0

是的你是對的。只有當您需要根據位置搜索Animal時,此方法纔是理想的。但如果它是一個50x50矩陣,循環遍歷整個矩陣的時間開銷可能可以忽略不計。另外,您應該考慮這個請求的頻率。這完全取決於你的目標用例。 – 2011-06-06 10:50:15

0

您可以使用類似以前的答案,但與另一個數據結構,而不是二維數組。如稀疏數組,有序列表或散列表。這將提供更快的查找速度,但動物插入或移動較慢。它仍然可以在任何地點執行不超過1只動物的要求。