質問

I am designing a system, I have not yet implemented first I am just diagraming it and then will code it, I want to ask one simple question:

What to do when we are using both inheritance and composition at the same time?

For example, in a hotel, there are 2 kinds of room standard room and Twin room let us say. For this I can use inheritance concept and these 2 kinds of rooms will be derived class but i can also use composition and will make seperate class for standard and twin room, then will use this is my hotel class.

What should I do?

役に立ちましたか?

解決

This question is kinda vague and there are many details missing, yet I'll share some ideas...

First thing: while working on design of your application, what matters the most are the requirements.

You need to try to identify entities that will have some meaning in your system first. Let's say you know that there will be Hotel and Room. Note, that this relation is a composition already, mainly because:

  • room can be part of only 1 hotel, it is not shared among multiple hotels
  • once the hotel is destroyed, so are all rooms in it

in C++, composition usually means "by value", i.e. class Hotel could have Room room; that would be an object with automatic storage duration with its lifetime tied to the lifetime of instance of Hotel, with multiple rooms you could just put them to the vector yielding the same relationship:

class Room { ... };

class Hotel {
public:
    std::vector<Room> rooms;
};

(By the way, an aggregation would be most likely represented by a pointer or reference). This is another good example of composition:

enter image description here

If you know that there will be different kinds of rooms, first questions should be: will these objects have different behaviour? will my system treat them in different way? ...maybe you don't need to go for finer granularity than Room and everything that a concrete room will be specific with will be expressed with its attributes - size, number of beds, maybe dozens of boolean "has" flags ("has aircon", "has TV", "has microwave", ...), maybe all of its properties can be expressed with simple "type", values of which you would put into the enum.

他のヒント

I the case you site, I would have a room_type property on the room class, and I would set the type of the room_type property to an enumerated type with possible values of STANDARD and TWIN.

As long as there are not significant behavioral differences depending upon this type field, I would keep it simple.

If there are complicated behaviors, like predicting clean up based upon number of beds, changing pricing, and so on, I would use an abstract base class CRoom, and inherit CStdRoom and CTwinRoom from that, possibly setting a constant num_of_beds property in the class constructors.

You shouldn't use language inheritance to model business requirement inheritance. It just makes it too hard to modify or extend the business model. Language inheritance is for implementing features of your model, not the model itself.

Instead, derive all your objects from 'business object' or similar, to encapsulate common internal behaviour such as serialisation. Your classes can have types and you can use typeinfo, or you can use an explicit type field. Either way links between objects, whether inheritance-like or composition-like should be pointers (or index id fields) and collections (of pointers or index ids). [Your code snippet is fine, but pointers complicate memory management which integer ids avoid.]

Complicated behaviours should belong to other classes such as the Pricing, Cleaning, etc. There are other patterns to use in setting the relationships between business objects and business actions, but again avoid crystallising them using language features. You will regret it, if the system grows or changes even a bit.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top