Suggest a design pattern?
I've been pondering the best way to implement a certain kind of functionality... that being derived objects referencing other derived objects with the same base (including mutual referencing).
Below is the best (simple) example I could think of to illustrate the kind of problem: a house made up of 3 rooms (though开发者_如何学JAVA in practice it could be hundreds) each represented by its own derived class. Of course it won't work as it stands, it would cause a stack overflow (appropriately!)
Assuming each room in the example is specific to a room in an imaginary house, there should be no more than one instance of any subclass. Constructing lots of instances, even without the recursion, would be messy. That would make me think singleton if that weren't such a taboo... can anyone suggest something more appropriate?
Thank you!
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(); }
}
Your rooms should contain references to an instance of each other rooms - not new instances.
e.g. create a new Kitchen
, Hall
, Bedroom
. Then pass a reference of the Hall
to the Bedroom
, to the Kitchen
etc. That way you have your three objects, and they have references to the neighbouring rooms.
Kitchen k = new Kitchen();
Bedroom b = new Bedroom();
k.addNeighbour(b);
etc.
(I'd normally construct a Kitchen
with appropriate references, but you appear to have circular references, so that's not so easy)
If you really need only one instance of each, then check out the singleton pattern. However I wouldn't enforce that unless strictly necessary. After all, lots of houses have more than one bedroom!
You really need to encapsulate (Is this the right word?) your model further.
public class House
{
private readonly Hall hall = new Hall();
private readonly Kitchen kitchen = new Kitchen();
// etc
public House()
{
hall.AddAdjacentRoom(kitchen);
// etc
}
}
All you need to do is avoid instantiating one room within the constructor of another. You'll need to instantiate all of your rooms (Kitchen k = new Kitchen(); Hall h = new Hall();), and then add the connections (k.ConnectedRooms[0] = h; h.ConnectedRooms[0] = k;). Or, to be clever, create a method that mutually connects them:
public abstract class Room
{
public void Connect(Room r)
{
this.ConnectedRooms.Add(r);
r.ConnectedRooms.Add(this);
}
}
Assuming you change your connection arrays to lists, which is probably a good idea.
精彩评论