2011-06-03 87 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只动物的要求。