Two objects with dependencies for each other. Is t

2019-06-17 23:07发布

问题:

I am learning a lot about design patterns when I am building my own system for my projects. And I want to ask you about a design question that I can't find an answer to.

Currently I am building a little Chat-server using sockets, with multiple Clients. Right now I have three classes:

  1. Person-class which holds information like nick, age and a Room-object.
  2. Room-class which holds information like room-name, topic and a list of Persons currently in that room.
  3. Hotel-class which have a list of Persons and a list of Rooms on the server.

I have made a diagram to illustrate it:

I have a list of persons on the server in the Hotel-class because it would be nice to keep track of how many there are online right now (Without having to iterate through all of the rooms). The persons live in the Hotel-class because I would like to be able to search for a specific Person without searching the rooms.

Is this bad design? Is there another way of achieve it?

Thanks.

回答1:

The mutual dependency problem among the classes, strictly speaking, can be solved by using interfaces (abstract classes, if your language is e.g. C++ or Python) IRoom and IPerson; in pseudocode

interface IPerson
    IRoom getRoom()
    // etc

interface IRoom
    iter<IPerson> iterPerson()
    // etc

this makes only the interfaces mutually dependent on each other -- the actual implementations of the interfaces need only depend on the interfaces.

This also gives you plenty of leeway in terms of implementation, if you want avoid circular reference loops (which can be a bother e.g. in CPython by slowing down garbage collections) -- you could use weak references, an underlying relational database with a typical "one to many relationship" table, etc, etc. And for the first simple prototype you can use what's simplest in your chosen language (probably simple, and alas necessarily circular, references [[pointers, in C++]] with a Person referring to a Room and a Room to a list<Person>).



回答2:

I don't like it. A hotel contains rooms, and rooms contain people. People don't contain rooms, they belong to them.

You don't necessarily have to iterate to get your guest count. You could just keep a running count ($Hotel->total_guests) and modify it as it changes.



回答3:

In a larger system, it would be bad, but since from what I understand of your applications, these three classes are only use together, it's not much of a problem. Just make sure to name the person's member variables in a way that indicates that it contains a reference to a room, rather than an instance.

Also, unless it's for performance reasons (e.g. you will have a huge number of rooms), it would probably be cleaner to make a property or getter that would iterate over the rooms and collect the persons, rather than caching them in the hotel.



回答4:

Mutual dependency is not bad in its own right. Sometimes the data usage requires it.

I think about it in a different way. It'll be easier to maintain code that has fewer relationships in general-- mutual dependency or not. Just keep it as simple as possible. The only additionally trickiness with your situation is sometimes there's a check and egg problem, during create and delete sequences. You've got more links to bookkeep.

If you're asking about whether you need a list of persons on a hotel in this case, I think there are two answers. I'd start out by having your objects (in memory) supplying these relationships, but you do NOT need an additional join table between people and hotels in the database. If you are using Hibernate, it will automatically generate an efficient join for your if you ask it for the people in a hotel (it will join hotels on rooms.hotel_id for you).