我一直在思考实现某种功能的最佳方式......即派生对象引用具有相同基础的其他派生对象(包括相互引用)。
以下是我能想到的最好(简单)的例子来说明问题:一个由3个房间组成的房子(虽然在实践中可能有数百个房间),每个房间都有自己的派生类。当然它不能正常工作,它会导致堆栈溢出(适当!)
假设示例中的每个房间都特定于虚构房屋中的房间,则任何子类都应该只有一个实例。构建大量实例,即使没有递归,也会很混乱。这会让我觉得单身如果不是这样的禁忌......任何人都可以提出更合适的建议吗?
谢谢!
public abstract class Room
{
abstract public void DoAction();
public Room[] ConnectedRooms;
}
public class Kitchen : Room
{
public Kitchen() { ConnectedRooms = new Room[] { new Hall() }; }
public override void DoAction() { MakeTea(); }
}
public class Bedroom : Room
{
public Bedroom() { ConnectedRooms = new Room[] { new Hall() }; }
public override void DoAction() { Sleep(); }
}
public class Hall : Room
{
public Hall() { ConnectedRooms = new Room[] { new Hall(), new Bedroom() }; }
public override void DoAction() { LookOutWindow(); }
}
答案 0 :(得分:4)
您的房间应该包含引用到每个其他房间的实例 - 而不是新实例。
e.g。创建新的Kitchen
,Hall
,Bedroom
。然后将Hall
的引用传递给Bedroom
,再传递给Kitchen
等。这样你就有了三个对象,并且它们引用了相邻的房间。
Kitchen k = new Kitchen();
Bedroom b = new Bedroom();
k.addNeighbour(b);
等
(我通常使用适当的引用构造一个Kitchen
,但是你似乎有循环引用,所以这并不容易)
如果您确实只需要每个实例,请查看singleton pattern。但是,除非严格必要,否则我不会强制执行。毕竟,很多房子都有一间以上的卧室!
答案 1 :(得分:2)
你真的需要进一步封装(这是正确的词吗?)你的模型。
public class House
{
private readonly Hall hall = new Hall();
private readonly Kitchen kitchen = new Kitchen();
// etc
public House()
{
hall.AddAdjacentRoom(kitchen);
// etc
}
}
答案 2 :(得分:0)
您需要做的就是避免在另一个房间的构造函数中实例化一个房间。您需要实例化所有房间(Kitchen k = new Kitchen(); Hall h = new Hall();),然后添加连接(k.ConnectedRooms [0] = h; h.ConnectedRooms [0] = k;)。或者,要聪明一点,创建一个相互连接它们的方法:
public abstract class Room
{
public void Connect(Room r)
{
this.ConnectedRooms.Add(r);
r.ConnectedRooms.Add(this);
}
}
假设您将连接数组更改为列表,这可能是一个好主意。