Failing to see real value in Composite/Iterator design pattern - c++

I have situation which in theory is perhaps perfect fit for composite and iterator design pattern but the problem I have with these patterns is one can't access the underlying data structure which can be a deal breaker.
Sure I can have a shop in a mall in a city in a country and this makes whole-part relationship and if I make composite pattern of it I can run common methods on all objects (for most part) like what time a store/mall opens and closes but in reality we need more than that.
Take for example a simple task of loading such composite structure from an already saved file into a tree control. Now we really don't even which component is what so we can't even determine if a component should be parent, sibling or child in the tree. We essentially have to do some kind of type check to find out which composite pattern is against in the first place. This is particularly true with external iterator.
At first it seemed like these two patterns in combination has a bigger potential but now they seem of little use.
I am trying to find true justification of these two patterns. Where can it be used best other than the simple text book example like Print() cost() functions. Am I right that the composite has to be typecasted back to fill a tree control to reflect the hierarchy of composite when it is loaded from a file?

You don't need an iterator, you need a visitor.
Iterators are for objects that are uniform; your objects are definitely not uniform. Moreover, composite tends to work better when objects are used in a uniform way. One classic example is expressions that you calculate; another one is geometric figures that you render on screen. Again, your case is a poor fit for the classic composite pattern, because shops and counties do not have too much in common.
Fortunately, visitor fixes it all: define a visitor class that knows what to do with a city, a county, a mall, and a shop. Make each of these classes "visitable", and arrange them in a composite. Now the unifying property of your classes in a composite is that each one can be visited. The leaf classes will call back the visitor, and pass themselves as an argument. The branch classes will first pass themselves, and then pass the visitor to all their components. This would let you traverse the entire hierarchy in a nice and clean way.
class County;
class City;
class Mall;
class Shop;
struct ShoppingVisitor {
virtual void visitCounty(const County& county);
virtual void visitCity(const City& city);
virtual void visitMall(const Mall& mall);
virtual void visitShop(const Shop& shop);
};
struct ShoppingVisitable {
virtual void accept(ShoppingVisitor& visitor) const;
};
class County : public ShoppingVisitable {
vector<ShoppingVisitable*> children;
public:
virtual void accept(ShoppingVisitor& visitor) const {
visitor.visitCounty(*this);
for (int i = 0; i != children.size() ; i++) {
children[i]->accept(visitor);
}
}
};
class City : public ShoppingVisitable {
vector<ShoppingVisitable*> children;
public:
virtual void accept(ShoppingVisitor& visitor) const {
visitor.visitCity(*this);
for (int i = 0; i != children.size() ; i++) {
children[i]->accept(visitor);
}
}
};
struct Mall : public ShoppingVisitable {
virtual void accept(ShoppingVisitor& visitor) const {
visitor.visitMall(*this);
}
};
struct Shop : public ShoppingVisitable {
virtual void accept(ShoppingVisitor& visitor) const {
visitor.visitShop(*this);
}
};

An example of an stl compliant external iterator of a composite, see this composite-iterator repository on github. It is a forward iterator. *iter returns the base class, Node.
The composite is the file system example from Pattern Hatching. See p. 25 of these slides for the description and class diagrams. Directory is the composite. The leaf nodes are File instances, and the base component class for both is Node.
Example
Directory::iterator iter_current = top.begin();
Directory::iterator iter_end = top.end();
for (;iter_current != iter_end; ++iter_current) {
Node &node = *iter_current;
cout << "[address: " << hex << &node << "] " << node.getName();
if (dynamic_cast<Directory*>(&node) ) {
cout << " is a Directory ";
} else {
cout << " is a File ";
}
cout << endl;
}

Related

Composite pattern with variations in classes

I have a situation where class A, B, and C, all are derived from X to make a composite pattern.
Now A, B, and C are very similar but they do have different internal attributes. My question is how do I access their attributes and modify them once they are added to composite without typecasting it?
In my real example, the part-whole relationship perfectly makes sense and all elements support the main operation which is why I need it. That said individual classes in the composite does have different attributes and requires special operations.
Is there a way to decouple these special properties and functions related to them away from composite class but attach to them?
To put things in perspective, let's say we have composite merchandise (base class of composite) which has a price. Now a store is a merchandise, in it, a department is a merchandise, in which an actual item say a potis merchandise, it can have a pot-set with combination pots which is also merchandise and so on.
class Merchandise
{
public:
virtual void add(Merchandise* item) = 0;
virtual Merchandise* getMerchandise() = 0;
virtual void show() = 0;
// assume we have the following key operations here but I am not implementing them to keep this eitemample short
//virtual setPrice(float price) = 0;
//virtual float getPrice() = 0;
};
class Store : public Merchandise
{
vector< Merchandise*> deparments;
std::string storeName = "";
public:
Store(std::string store_name) : storeName(store_name) {}
virtual void add(Merchandise* item)
{
deparments.push_back(item);
}
virtual Merchandise* getMerchandise()
{
if (deparments.size() > 0)
return deparments[0];
return 0;
}
virtual void show()
{
cout << "I am Store " << storeName << " and have following " << deparments.size() << " departments" << endl;
for (unsigned int i = 0; i < deparments.size(); i++)
{
deparments[i]->show();
}
}
};
class Department : public Merchandise
{
std::string depName;
vector<Merchandise*> items;
public:
Department(std::string dep_name) : depName(dep_name) {}
virtual void add(Merchandise* item)
{
items.push_back(item);
}
virtual Merchandise* getMerchandise()
{
if (items.size() > 0)
return items[0];
return 0;
}
virtual void show()
{
cout << "I am department " << depName << " and have following " << items.size() << " items" << endl;
for (unsigned int i = 0; i < items.size(); i++)
{
items[i]->show();
}
}
};
class Shirt : public Merchandise
{
std::string shirtName;
public:
Shirt(std::string shirt_name) : shirtName(shirt_name) {}
virtual void add(Merchandise* item) {}
virtual Merchandise* getMerchandise() { return 0; }
virtual void show()
{
cout << "I am shirt " << shirtName << endl;
};
};
class Pot : public Merchandise
{
std::string potName;
public:
Pot(std::string pot_name) : potName(pot_name) {}
virtual void add(Merchandise* item) { }
virtual Merchandise* getMerchandise() { return 0; }
virtual void show()
{
cout << "I am pot " << potName << endl;
};
int num = 0;
};
class CookSet : public Merchandise
{
std::string cooksetName;
vector<Merchandise*> pots;
public:
CookSet(std::string cookset_name) : cooksetName(cookset_name) {}
vector<Merchandise*> listOfPots;
virtual void add(Merchandise* item) { pots.push_back(item); }
virtual Merchandise* getMerchandise() { return 0; }
virtual void show()
{
cout << "I am cookset " << cooksetName << " and have following " << pots.size() << " items" << endl;
for (unsigned int i = 0; i < pots.size(); i++)
{
pots[i]->show();
}
};
int num = 0;
};
int main()
{
// create a store
Store * store = new Store( "BigMart");
// create home department and its items
Department * mens = new Department( "Mens");
mens->add(new Shirt("Columbia") );
mens->add(new Shirt("Wrangler") );
// likewise a new composite can be dress class which is made of a shirt and pants.
Department * kitchen = new Department("Kitchen");
// create kitchen department and its items
kitchen->add(new Pot("Avalon"));
CookSet * cookset = new CookSet("Faberware");
cookset->add(new Pot("Small Pot"));
cookset->add(new Pot("Big pot"));
kitchen->add(cookset);
store->add( mens );
store->add(kitchen);
store->show();
// so far so good but the real fun begins after this.
// Firt question is, how do we even access the deep down composite objects in the tree?
// this wil not really make sense!
Merchandise* item = store->getMerchandise()->getMerchandise();
// Which leads me to want to add specific method to CStore object like the following to retrieve each department
// but then does this break composite pattern? If not, how can I accomodate these methods only to CStore class?
//store->getMensDept();
//store->getsKitchenDept();
// Likewise a shirt class will store different attributes of a shirt like collar size, arm length etc, color.
// how to retrieve that?
// Other operations is, say if item is cookset, set it on 20% sale.
// Another if its a shirt and color is orange, set it on 25% sale (a shirt has a color property but pot doesn't).
// how to even dispaly particular attributes of that item in a structure?
// item->getAttributes();
return 0;
}
The problem is with this line once I have filled up the composite.
Merchandise* item = store->getMerchandise()->getMerchandise();
First, from my code structure, I know this should be a certain type but as a best practice, we are not supposed to typecast this!? But I do want to change its properties which are unique to it so how do I achieve that?
Assume this store sells shirts as well and I want to change its properties (or even just to display them!), it is very different from a pot.
What would be the best approach here? I think if we can somehow decouple the unique properties of each composite into different classes, this way composite will stay leaner too but not sure how to achieve that.
I assume, in real life, there is no perfect composite and the constituent classes will have some differences. How do we handle that?
Update
Please note I have used the merchandise example to explain the problem. In my real example, A, B, C are all derived from X. A contains multiple B which contains multiple C items. When an operation is performed on A, it needs to be performed on its constituents and that's why I am using composite. But then, each composite does have different attributes. Is composite not a good fit for this?
I think you are looking for the visitor design pattern, it keeps clean interfaces and makes code much more flexible.
class Shirt;
class Pot;
class visitor{
public:
//To do for each component types:
virtual void visit(Shirt&) =0;
virtual void visit(Pot&) =0;
};
class Merchandise
{
public:
//...
//Provides a default implementation for the acceptor that
//that do nothing.
virtual void accept(visitor& x){}
// assume we have the following key operations here but I am not implementing them to keep this eitemample short
//virtual setPrice(float price) = 0;
//virtual float getPrice() = 0;
// => implementable with a visitor
};
class Store : public Merchandise
{
//...
void accept(visitor& v) override
{
for (unsigned int i = 0; i < deparments.size(); i++)
{
//forward the visitor to each component of the store.
//do the same for departments
deparments[i]->accept(v);
}
}
};
class Shirt : public Merchandise
{
//...
void accept(visitor& v) override{
//now *this as the type Shirt&, pass this to the visitor.
v.visit(*this);
}
};
class Pot : public Merchandise
{
//...
void accept(visitor& v) override{
v.visit(*this);
}
};
class SpecialPromotion
:public visitor{
public:
void visit(Shirt& s) override {
//25% discount on orange shirts, 15% otherwise;
if (s.color="orange")
s.price*=0.75;
else
s.price*=0.85
}
void visit(Pot& p) override{
//one pot offered for each pot pack
++p.num;
}
};
//example of usage:
void apply_special_promotion(Store& s){
SpecialPromotion x;
s.accept(x);
}
class EstimateStockMass
:public visitor{
public:
double mass=0;
void visit(Shirt& s) override {
if (s.size="XL") mass+=0.5;
else mass+=0.1;
}
void visit(Pot& p) override{
mass += p.num * 1.2;
}
};
//example of usage:
double get_stock_mass(Store& s){
EstimateStockMass x;
s.accept(x);
return x.mass;
}
It seems like what you want to do is gathering RTTI (Run-time type information), so dynamic_cast is the solution. Also, if you are using C++17, I will recommend you use std::variant (or boost::variant if you are using lower version of C++ but are using boost.) If you do not want to use them, then maybe you can make your add a template function and returns a reference to the underlying type.
By the way
in your main there are a bunch of dynamic allocations that never get deallocated. Use smart pointers if you have C++ with version at least C++11.
your base classes do not have virtual destructors, this will cause huge problems when destroying your store
Don't use using namespace std
If you have C++11, use override keyword when you want to override a virtual function
You should mark show() const.
Merchandise: a commodity offered for sale
Now a store is a merchandise,
This is true only if you are selling the store. Otherwise it is better described as a container of merchandise, not a composite.
Even if you are in the business of selling stores, it might (depending on the context of the program) be prudent to treat it as a different kind of merchandise (different base class) since the selling environment is rather different.
in it, a department is a merchandise,
Departments within a store are rarely sold to other stores, so I highly doubt this claim. Again, you have something that contains merchandise, not something composed of merchandise.
in which an actual item say a pot is merchandise, it can have a pot-set with combination pots which is also merchandise and so on.
Yes, this much is good. Pots are offered for sale. A pot-set combination sounds like a good example of composite merchandise, as the set is offered for sale, and its components might be packaged and offered for sale separately, perhaps even on the same shelf.
Speaking of the shelf, that would be another example of a container of merchandise.
It looks like you might be after containers rather than composites. A store could have a vector of departments (or perhaps a set if you want to find them by name). The department in turn could have a container of merchandise within that department. Or perhaps the department would contain aisles, which then contain shelves, which then contain merchandise.
If you need the inventory of the entire store, there are a few options. One would be to have the store iterate over its departments, which then iterate over their inventories. Ideally, you would implement this within the store class so that code outside the class does not need to know about this structure. Another option would be for the store to maintain its own container of merchandise. This would mean that a single item of merchandise would logically be in multiple containers (e.g. a store's and a department's). This suggests using containers of shared_ptr, so that each item of merchandise is still represented by a single data object.
Regardless of the implementation chosen, the relationship between "store" and "merchandise" is better described as "has" rather than "is".
Concerning Your Design Choices
Let's compare the GoF book description of the intent of the Composite pattern with your requirements:
Compose objects into tree structures that represent whole-part hierarchies.
In your example a shirt is not part of a shop, and a shop is not really an item of merchandise.
You say this does make sense in your actual code, but I can only comment on the code you actually showed.
Composite lets clients treat individual objects and compositions of objects uniformly.
In your comment you say you don't really want to treat each type of object uniformly.
So, it's at least not obvious that Composite is a good fit, because the description doesn't match your use case (at best, it half-fits your described use case but not your sample code).
For comparison, the motivating example from that book is a drawing app, where treating the main canvas as a Drawable object containing other Drawable sub-objects (of different types like lines, polygons and text) is useful for rendering. In that case each object is a drawable part of the drawable whole, and it focuses on the case when you do want to treat them uniformly (ie, issuing a single draw call to the top-level canvas).
A match has an innings (has score/result), both side which are playing has their inning (has scores), then each player who is playing has his innings (score with more details). When match progresses, an event is added to the match which than is added to current innings and than current player innings. So I build up score this way but at the end I want to display it and each innings type is rather different and setting up current state requires different operations.
OK, an innings is part of a match, but do you have any more levels? Does an innings consist of balls or other events, or is it just ... an innings number, a player and a score?
If you can easily model a game as a list of innings, and link each innings to a player for per-player reports, that seems a lot simpler.
Even if you have another level, if you only want to deal with objects heterogeneously (according to their different types, instead of homogeneously as if they're all the same), you can just write that structure explicitly.
Concerning Your Composite Implementation
The getMerchandise interface is poor. Why does it return only the first of potentially many objects? Why do you need to get them anyway?
You mention two use cases:
changing an object's properties
Presumably you know which object you want to alter, right? Say you want to change the price of the object loosely identified as Mens>Shirts>Wrangler. Either
ask the store to forward a Visitor to that object by name (so the store finds the department called "Mens" and asks that to forward the Visitor to a child matching Shirts>Wrangler).
just find the Shirt("Wrangler") object directly in some other index (eg. by stock number) and deal with it directly. You don't have to do everything via the Composite pattern even if you do use it.
displaying an object
But the whole point of the Composite pattern is that every object should implement a virtual display (or whatever) method. You use this when you want to let every type know how to display itself.

How to get access to variable in child class without initialize it in parent class in getter

Hi there I've a little problem with my course work in university, let me show you.
I've one parent class called Organisation and two child classess called Insurance and Manufacturem, also I've a container Deque. Class Insurance has field called statutory_capital it's float and my task is to show organisation, which has statutory_capital more, than derived from user.
That's Deque.h :
#pragma once
#include "Organisation.h"
struct Node
{
Node *Next;
Organisation* data;
};
class Deque
{
public:
void Do_request();
private:
Node *Front;
Node *Back;
};
That's Organisation.h :
#pragma once
#include <string>
using namespace std;
class Organisation
{
protected:
int workers;
string name;
float experience;
//float statutory_capital; If I uncomment this and get_statutory_capital everything works
public:
Organisation();
Organisation(string Name, float Experience, int Workers);
virtual void show() = 0;
virtual string get_name();
virtual int get_workers();
//virtual float get_statutory_capital();
};
Here is method Do_request() to find organisations with statutory capital more than written by user :
void Deque::Do_request()
{
if (Front == NULL)
{
cout << "The deque is empty" << endl;
return;
}
Node *temp = Front;
Insurance tmp;
Insurance *ptr_insurance;
float test_statutory_capital;
cout << "Write the statutory capital to find: ";
cin >> test_statutory_capital;
while (temp != NULL)
{
ptr_insurance = new Insurance(temp->data);
cout << "TESt" << tmp.get_statutory_capital();
if (ptr_insurance != NULL)
{
if (tmp.get_statutory_capital() > test_statutory_capital)
{
cout << "Insurance with capital more than test: "<< temp->data->get_name() << "\n";
}
}
temp = temp->Next;
}
}
What should I do not adding a variable statutory_capital to my parent classOrganisation, I don't need it here, cause my class Manufacture doesn't have the field statutory capital. Thanks!
Your assignment is tricky. Only Insurance has statutory_capital, but you have to find out what statutory capital an organisation has without knowing if it's an Insurance or not. So here's a contradiction. On one hand, the base class shouldn't have knowledge about its specific derived classes. On the other hand, you need to find out information about a specific derived class having only a bunch of base class pointers in hand.
There are several solutions out there but they all will involve different trade-offs.
You can introduce the knowledge about statutory capital to your base class. The recommended way is to add a virtual function get_statutory_capital(). The default implementation will return 0 (or a negative number, indicating that this organisation doesn't have a notion of statutory capital). Relevant derived classes will override it as they see fit. The downside of this is the base class potentially growing out of control as you add more and more child-specific functionality to its interface.
You can check the type of the organisation at run time (using e.g. dynamic_cast). If this particular organisation has statutory capital, process it; if not, leave it alone. The recommended way of doing this is creating a special class Has_statutory_capital with one public pure virtual method get_statutory_capital(). Add this base class to all organisations that have statutory_capital. The downside of this is having to use dynamic_cast, which makes the design more complicated and unwieldy.
You can keep organisations that have statutory capital in a separate list (again, derive them from Has_statutory_capital). This again makes the design more complicated, in a different way.
You can make your classes visitable and use the Visitor pattern to process the statutory capital information. The downside is the usual downside of the visitor pattern: a cyclic dependency.
If most of this goes over your head, don't worry and just use the first solution.

Flexible design despite strongly dependent classes

I'm working on a code which needs to be extremely flexible in nature, i.e. especially very easy to extend later also by other people. But I'm facing a problem now about which I do not even know in principal how to properly deal with:
I'm having a rather complex Algorithm, which at some point is supposed to converge. But due to its complexity there are several different criteria to check for convergence, and depending on the circumstances (or input) I would want to have different convergence criteria activated. Also it should easily be possible to create new convergence criteria without having to touch the algorithm itself. So ideally I would like to have an abstract ConvergenceChecker class from which I can inherit and let the algorithm have a vector of those, e.g. like this:
//Algorithm.h (with include guards of course)
class Algorithm {
//...
vector<ConvergenceChecker*> _convChecker;
}
//Algorithm.cpp
void runAlgorithm() {
bool converged=false;
while(true){
//Algorithm performs a cycle
for (unsigned i=0; i<_convChecker.size(); i++) {
// Check for convergence with each criterion
converged=_convChecker[i]->isConverged();
// If this criterion is not satisfied, forget about the following ones
if (!converged) { break; }
}
// If all are converged, break out of the while loop
if (converged) { break; }
}
}
The problem with this is that each ConvergenceChecker needs to know something about the currently running Algorithm, but each one might need to know totally different things from the algorithm. Say the Algorithm changes _foo _bar and _fooBar during each cycle, but one possible ConvergenceChecker only needs to know _foo, another one _foo and _bar, and it might be that some day a ConvergenceChecker needing _fooBar will be implemented. Here are some ways I already tried to solve this:
Give the function isConverged() a large argument list (containing _foo, _bar, and _fooBar). Disadvantages: Most of the variables used as arguments will not be used in most cases, and if the Algorithm would be extended by another variable (or a similar algorithm inherits from it and adds some variables) quite some code would have to be modified. -> possible, but ugly
Give the function isConverged() the Algorithm itself (or a pointer to it) as an argument. Problem: Circular dependency.
Declare isConverged() as a friend function. Problem (among others): Cannot be defined as a member function of different ConvergenceCheckers.
Use an array of function pointers. Does not solve the problem at all, and also: where to define them?
(Just came up with this while writing this question) Use a different class which holds the data, say AlgorithmData having Algorithm as a friend class, then provide the AlgorithmData as a function argument. So, like 2. but maybe getting around circular dependency problems. (Did not test this yet.)
I'd be happy to hear your solutions about this (and problems you see with 5.).
Further notes:
Question title: I'm aware that 'strongly dependent classes' already says that most probably one is doing something very wrong with designing the code, still I guess a lot of people might end up with having that problem and would like to hear possibilities to avoid it, so I'd rather keep that ugly expression.
Too easy?: Actually the problem I presented here was not complete. There will be a lot of different Algorithms in the code inheriting from each other, and the ConvergenceCheckers should of course ideally work in appropriate cases without any further modification even if new Algorithms come up. Feel free to comment on this as well.
Question style: I hope the question is neither too abstract nor too special, and I hope it did not get too long and is understandable. So please also don't hesitate to comment on the way I ask this question so that I can improve on that.
Actually, your solution 5 sounds good.
When in danger of introducing circular dependencies, the best remedy usually is to extract the part that both need, and moving it to a separate entity; exactly as extracting the data used by the algorithm into a separate class/struct would do in your case!
Another solution would be passing your checker an object that provides the current algorithm state in response to parameter names expressed as string names. This makes it possible to separately compile your conversion strategies, because the interface of this "callback" interface stays the same even if you add more parameters to your algorithm:
struct AbstractAlgorithmState {
virtual double getDoubleByName(const string& name) = 0;
virtual int getIntByName(const string& name) = 0;
};
struct ConvergenceChecker {
virtual bool converged(const AbstractAlgorithmState& state) = 0;
};
That is all the implementers of the convergence checker need to see: they implement the checker, and get the state.
You can now build a class that is tightly coupled with your algorithm implementation to implement AbstractAlgorithmState and get the parameter based on its name. This tightly coupled class is private to your implementation, though: the callers see only its interface, which never changes:
class PrivateAlgorithmState : public AbstractAlgorithmState {
private:
const Algorithm &algorithm;
public:
PrivateAlgorithmState(const Algorithm &alg) : algorithm(alg) {}
...
// Implement getters here
}
void runAlgorithm() {
PrivateAlgorithmState state(*this);
...
converged=_convChecker[i]->converged(state);
}
Using a separate data/state structure seems easy enough - just pass it to the checker as a const reference for read-only access.
class Algorithm {
public:
struct State {
double foo_;
double bar_;
double foobar_;
};
struct ConvergenceChecker {
virtual ~ConvergenceChecker();
virtual bool isConverged(State const &) = 0;
}
void addChecker(std::unique_ptr<ConvergenceChecker>);
private:
std::vector<std::unique_ptr<ConvergenceChecker>> checkers_;
State state_;
bool isConverged() {
const State& csr = state_;
return std::all_of(checkers_.begin(),
checkers_.end(),
[csr](std::unique_ptr<ConvergenceChecker> &cc) {
return cc->isConverged(csr);
});
}
};
Maybe the decorator pattern can help in simplifying an (unknown) set of convergence checks. This way you can keep the algorithm itself agnostic to what convergence checks may occur and you don't require a container for all the checks.
You would get something along these lines:
class ConvergenceCheck {
private:
ConvergenceCheck *check;
protected:
ConvergenceCheck(ConvergenceCheck *check):check(check){}
public:
bool converged() const{
if(check && check->converged()) return true;
return thisCheck();
}
virtual bool thisCheck() const=0;
virtual ~ConvergenceCheck(){ delete check; }
};
struct Check1 : ConvergenceCheck {
public:
Check1(ConvergenceCheck* check):ConvergenceCheck(check) {}
bool thisCheck() const{ /* whatever logic you like */ }
};
You can then make arbitrary complex combinations of convergence checks while only keeping one ConvergenceCheck* member in Algorithm. For example, if you want to check two criteria (implemented in Check1 and Check2):
ConvergenceCheck *complex=new Check2(new Check1(nullptr));
The code is not complete, but you get the idea. Additionally, if you are a performance fanatic and are afraid of the virtual function call (thisCheck), you can apply the curiously returning template pattern to eliminate that.
Here is a complete example of decorators to check constraints on an int, to give an idea of how it works:
#include <iostream>
class Check {
private:
Check *check_;
protected:
Check(Check *check):check_(check){}
public:
bool check(int test) const{
if(check_ && !check_->check(test)) return false;
return thisCheck(test);
}
virtual bool thisCheck(int test) const=0;
virtual ~Check(){ delete check_; }
};
class LessThan5 : public Check {
public:
LessThan5():Check(NULL){};
LessThan5(Check* check):Check(check) {};
bool thisCheck(int test) const{ return test < 5; }
};
class MoreThan3 : public Check{
public:
MoreThan3():Check(NULL){}
MoreThan3(Check* check):Check(check) {}
bool thisCheck(int test) const{ return test > 3; }
};
int main(){
Check *morethan3 = new MoreThan3();
Check *lessthan5 = new LessThan5();
Check *both = new LessThan5(new MoreThan3());
std::cout << morethan3->check(3) << " " << morethan3->check(4) << " " << morethan3->check(5) << std::endl;
std::cout << lessthan5->check(3) << " " << lessthan5->check(4) << " " << lessthan5->check(5) << std::endl;
std::cout << both->check(3) << " " << both->check(4) << " " << both->check(5);
}
Output:
0 1 1
1 1 0
0 1 0

Object oriented design for hotel reservation system

I am practicing object oriented design for an upcoming interview. My question is about the design for a hotel reservation system:
- The system should be able to return an open room of a specific type or return all the open rooms in the hotel.
- There are many types of rooms in hotel like regular, luxury, celebrity and so on.
So far I have come up with following classes:
Class Room{
//Information about room
virtual string getSpecifications(Room *room){};
}
Class regularRoom: public Room{
//get specifications for regular room
}
Class luxuryRoom: public Room{
//get specifications for regular room
}
//Similarly create as many specialized rooms as you want
Class hotel{
vector<Room *>openRooms; //These are all the open rooms (type casted to Room type pointer)
Public:
Room search(Room *aRoom){ //Search room of a specific type
for(int i=0;i<openRooms.size();i++){
if(typeid(*aRoom)==typeid(*openRooms[i])) return *openRooms[i];
}
}
vector<Room> allOpenRooms(){//Return all open rooms
...
}
}
I am confused about the implementation of hotel.search() method where I am checking the type (which I believe should be handled by polymorphism in some way). Is there a better way of designing this system so that the search and allOpenRooms methods can be implemented without explicitly checking the type of the objects?
Going through the sub-class objects asking what type they are isn't really a good illustration of o-o design. You really need something you want to do to all rooms without being aware of what type each one is. For example print out the daily room menu for the room (which might be different for different types).
Deliberately looking for the sub-class object's type, while not being wrong, is not great o-o style. If you just want to do that, as the other respondents have said, just have "rooms" with a set of properties.
You could always let a room carry it's real type, instead of comparing the object type:
enum RoomType
{
RegularRoom,
luxuryRoom
};
class Room{
public:
explicit Room(RoomType room_type) : room_type_(room_type) { }
virtual ~Room(){}
RoomType getRoomType() const { return room_type_; }
private:
RoomType room_type_; // carries room type
};
class regularRoom: public Room{
public:
regularRoom() : Room(RegularRoom){ }
};
Room search(Room *aRoom)
{
//Search room of a specific type
for(size_t i=0;i<openRooms.size();i++)
{
if (aRoom->getRoomType() == RegularRoom) // <<-- compare room type
{
// do something
}
}
};
Do the different types of rooms have different behavior? From
the description you give, this is not a case where inheritance
should be used. Each room simply has an attribute, type, which
is, in its simplest form, simply an enum.
The simplest way is to have a Room type enumeration as #billz suggest you. The problem with tis way is that you must not forget to add a value to the enumeration and use it once every time you add a new type of Room to the system. You have to be sure you use the enum values only once, one time per class.
But, on the other hand, inheritance bassed dessigns only have sense if the types of the hierarchy shares a common behaviour. In other words, you want to use them in the same way, regardless of its type. IMPO, an OO/inheritance dessign is not the better way to do this.
The freak and scalable way I do this type of things is through typelists.
Normally, you have different search criteria for every type in your system. And, in many cases, the results of this search are not the same for different types of your system (Is not the ssame to search a luxury room and to search a normal room, you could have different search criteria and/or want different search results data).
For this prupose, the system has three typelists: One containing the data types, one containing the search criteria types, and one containing the search results types:
using system_data_types = type_list<NormalRoom,LuxuryRoom>;
using search_criteria_types = type_list<NormalRoomsCriteria,LuxuryRoommsCriteria>;
using search_results_types = type_list<NormalRoomSearchResults,LuxuryRoomSearchResults>;
Note that type_lists are sorted in the same manner. This is important, as I show below.
So the implementation of the search engine is:
class SearchEngine
{
private:
std::vector<VectorWrapper*> _data_lists; //A vector containing each system data type in its own vector. (One vector for NormalRoom, one for LuxuryRoom, etc)
//This function returns the vector that stores the system data type passed.
template<typename T>
std::vector<T>& _get_vector() {...} //Implementation explained below.
public:
SearchEngine() {...}//Explanation below.
~SearchEngine() {...}//Explanation below.
//This function adds an instance of a system data type to the "database".
template<typename T>
void addData(const T& data) { _get_vector<T>().push_back( data ); }
//The magic starts here:
template<typename SEARCH_CRITERIA_TYPE>//This template parameter is deduced by the compiler through the function parameter, so you can ommit it.
typename search_results_types::type_at<search_criteria_types::index_of<SEARCH_CRITERIA_TYPE>> //Return value (The search result that corresponds to the passed criteria. THIS IS THE REASON BECAUSE THE TYPELISTS MUST BE SORTED IN THE SAME ORDER.
search( const SEARCH_CRITERIA_TYPE& criteria)
{
using system_data_type = system_data_types::type_at<search_criteria_types::index_of<SEARCH_CRITERIA_TYPE>>; //The type of the data to be searched.
std::vector<system_data_type>& data = _get_vector<system_data_type>(); //A reference to the vector where that type of data is stored.
//blah, blah, blah (Search along the vector using the criteria parameter....)
}
};
And the search engine can be used as follows:
int main()
{
SearchEngine engine;
engine.addData(LuxuryRoom());
engine.addData(NormalRoom());
auto luxury_search_results = engine.search(LuxuryRoomCriteria()); //Search LuxuryRooms with the specific criteria and returns a LuxuryRoomSearchResults instance with the results of the search.
auto normal_search_results = engine.search(NormalRoomCriteria()); //Search NormalRooms with the specific criteria and returns a NormalRoomSearchResults instance with the results of the search.
}
The engine is based on store one vector for every system data type. And the engine uses a vector that stores that vectors.
We cannot have a polymorphic reference/pointer to vectors of different types, so we use a wrapper of a std::vector:
struct VectorWrapper
{
virtual ~VectorWrapper() = 0;
};
template<typename T>
struct GenericVectorWrapper : public VectorWrapper
{
std::vector<T> vector;
~GenericVectorWrapper() {};
};
//This template class "builds" the search engine set (vector) of system data types vectors:
template<int type_index>
struct VectorBuilder
{
static void append_data_type_vector(std::vector<VectorWrapper*>& data)
{
data.push_back( new GenericVectorWrapper< system_data_types::type_at<type_index> >() ); //Pushes back a vector that stores the indexth type of system data.
VectorBuilder<type_index+1>::append_data_type_vector(data); //Recursive call
}
};
//Base case (End of the list of system data types)
template<>
struct VectorBuilder<system_data_types::size>
{
static void append_data_type_vector(std::vector<VectorWrapper*>& data) {}
};
So the implementation of SearchEngine::_get_vector<T> is as follows:
template<typename T>
std::vector<T>& get_vector()
{
GenericVectorWrapper<T>* data; //Pointer to the corresponing vector
data = dynamic_cast<GenericVectorWrapper<T>*>(_data_lists[system_data_types::index_of<T>]); //We try a cast from pointer of wrapper-base-class to the expected type of vector wrapper
if( data )//If cast success, return a reference to the std::vector<T>
return data->vector;
else
throw; //Cast only fails if T is not a system data type. Note that if T is not a system data type, the cast result in a buffer overflow (index_of<T> returns -1)
}
The constructor of SearchEngine only uses VectorBuilder to build the list of vectors:
SearchEngine()
{
VectorBuilder<0>::append_data_type_vector(_data_list);
}
And the destructor only iterates over the list deleting the vectors:
~SearchEngine()
{
for(unsigned int i = 0 ; i < system_data_types::size ; ++i)
delete _data_list[i];
}
The advantages of this dessign are:
The search engine uses exactly the same interface for different searches (Searches with different system data types as target). And the process of "linking" a data type to its corresponding search criteria and results is done at compile-time.
That interface is type safe: A call to SearchEngine::search() returns a type of results based only on the search criteria passed. Assignament results errors are detected at compile-time. For example: NormalRoomResults = engine.search(LuxuryRoomCriteria()) generates a compilation error (engine.search<LuxuryRoomCriteria> returns LuxuryRoomResults).
The search engine is fully scalable: To add a new datatype to the system, you must only go to add the types to the typelists. The implementation of the search engine not changes.
Room Class
class Room{
public:
enum Type {
Regular,
Luxury,
Celebrity
};
Room(Type rt):roomType(rt), isOpen(true) { }
Type getRoomType() { return roomType; }
bool getRoomStatus() { return isOpen; }
void setRoomStatus(bool isOpen) { this->isOpen = isOpen; }
private:
Type roomType;
bool isOpen;
};
Hotel Class
class Hotel{
std::map<Room::Type, std::vector<Room*>> openRooms;
//std::map<Room::Type, std::vector<Room*>> reservedRooms;
public:
void addRooms(Room &room) { openRooms[room.getRoomType()].push_back(&room); }
auto getOpenRooms() {
std::vector<Room*> allOpenRooms;
for(auto rt : openRooms)
for(auto r : rt.second)
allOpenRooms.push_back(r);
return allOpenRooms;
}
auto getOpenRoomsOfType(Room::Type rt) {
std::vector<Room*> OpenRooms;
for(auto r : openRooms[rt])
OpenRooms.push_back(r);
return OpenRooms;
}
int totalOpenRooms() {
int roomCount=0;
for(auto rt : openRooms)
roomCount += rt.second.size();
return roomCount;
}
};
Client UseCase:
Hotel Marigold;
Room RegularRoom1(Room::Regular);
Room RegularRoom2(Room::Regular);
Room LuxuryRoom(Room::Luxury);
Marigold.addRooms(RegularRoom1);
Marigold.addRooms(RegularRoom2);
Marigold.addRooms(LuxuryRoom);
auto allRooms = Marigold.getOpenRooms();
auto LRooms = Marigold.getOpenRoomsOfType(Room::Luxury);
auto RRooms = Marigold.getOpenRoomsOfType(Room::Regular);
auto CRooms = Marigold.getOpenRoomsOfType(Room::Celebrity);
cout << " TotalOpenRooms : " << allRooms.size()
<< "\n Luxury : " << LRooms.size()
<< "\n Regular : " << RRooms.size()
<< "\n Celebrity : " << CRooms.size()
<< endl;
TotalOpenRooms : 4
Luxury : 2
Regular : 2
Celebrity : 0
If you really want to check that a room is of the same type as some other room, then typeid() is as good as any other method - and it's certainly "better" (from a performance perspective, at least) to calling a virtual method.
The other option is to not have separate classes at all, and store the roomtype as a member variable (and that is certainly how I would design it, but that's not a very good design for learning object orientation and inheritance - you don't get to inherit when the base class fulfils all your needs).

Practical use of dynamic_cast?

I have a pretty simple question about the dynamic_cast operator. I know this is used for run time type identification, i.e., to know about the object type at run time. But from your programming experience, can you please give a real scenario where you had to use this operator? What were the difficulties without using it?
Toy example
Noah's ark shall function as a container for different types of animals. As the ark itself is not concerned about the difference between monkeys, penguins, and mosquitoes, you define a class Animal, derive the classes Monkey, Penguin, and Mosquito from it, and store each of them as an Animal in the ark.
Once the flood is over, Noah wants to distribute animals across earth to the places where they belong and hence needs additional knowledge about the generic animals stored in his ark. As one example, he can now try to dynamic_cast<> each animal to a Penguin in order to figure out which of the animals are penguins to be released in the Antarctic and which are not.
Real life example
We implemented an event monitoring framework, where an application would store runtime-generated events in a list. Event monitors would go through this list and examine those specific events they were interested in. Event types were OS-level things such as SYSCALL, FUNCTIONCALL, and INTERRUPT.
Here, we stored all our specific events in a generic list of Event instances. Monitors would then iterate over this list and dynamic_cast<> the events they saw to those types they were interested in. All others (those that raise an exception) are ignored.
Question: Why can't you have a separate list for each event type?
Answer: You can do this, but it makes extending the system with new events as well as new monitors (aggregating multiple event types) harder, because everyone needs to be aware of the respective lists to check for.
A typical use case is the visitor pattern:
struct Element
{
virtual ~Element() { }
void accept(Visitor & v)
{
v.visit(this);
}
};
struct Visitor
{
virtual void visit(Element * e) = 0;
virtual ~Visitor() { }
};
struct RedElement : Element { };
struct BlueElement : Element { };
struct FifthElement : Element { };
struct MyVisitor : Visitor
{
virtual void visit(Element * e)
{
if (RedElement * p = dynamic_cast<RedElement*>(e))
{
// do things specific to Red
}
else if (BlueElement * p = dynamic_cast<BlueElement*>(e))
{
// do things specific to Blue
}
else
{
// error: visitor doesn't know what to do with this element
}
}
};
Now if you have some Element & e;, you can make MyVisitor v; and say e.accept(v).
The key design feature is that if you modify your Element hierarchy, you only have to edit your visitors. The pattern is still fairly complex, and only recommended if you have a very stable class hierarchy of Elements.
Imagine this situation: You have a C++ program that reads and displays HTML. You have a base class HTMLElement which has a pure virtual method displayOnScreen. You also have a function called renderHTMLToBitmap, which draws the HTML to a bitmap. If each HTMLElement has a vector<HTMLElement*> children;, you can just pass the HTMLElement representing the element <html>. But what if a few of the subclasses need special treatment, like <link> for adding CSS. You need a way to know if an element is a LinkElement so you can give it to the CSS functions. To find that out, you'd use dynamic_cast.
The problem with dynamic_cast and polymorphism in general is that it's not terribly efficient. When you add vtables into the mix, it only get's worse.
When you add virtual functions to a base class, when they are called, you end up actually going through quite a few layers of function pointers and memory areas. That will never be more efficient than something like the ASM call instruction.
Edit: In response to Andrew's comment bellow, here's a new approach: Instead of dynamic casting to the specific element type (LinkElement), instead you have another abstract subclass of HTMLElement called ActionElement that overrides displayOnScreen with a function that displays nothing, and creates a new pure virtual function: virtual void doAction() const = 0. The dynamic_cast is changed to test for ActionElement and just calls doAction(). You'd have the same kind of subclass for GraphicalElement with a virtual method displayOnScreen().
Edit 2: Here's what a "rendering" method might look like:
void render(HTMLElement root) {
for(vector<HTLMElement*>::iterator i = root.children.begin(); i != root.children.end(); i++) {
if(dynamic_cast<ActionElement*>(*i) != NULL) //Is an ActionElement
{
ActionElement* ae = dynamic_cast<ActionElement*>(*i);
ae->doAction();
render(ae);
}
else if(dynamic_cast<GraphicalElement*>(*i) != NULL) //Is a GraphicalElement
{
GraphicalElement* ge = dynamic_cast<GraphicalElement*>(*i);
ge->displayToScreen();
render(ge);
}
else
{
//Error
}
}
}
Operator dynamic_cast solves the same problem as dynamic dispatch (virtual functions, visitor pattern, etc): it allows you to perform different actions based on the runtime type of an object.
However, you should always prefer dynamic dispatch, except perhaps when the number of dynamic_cast you'd need will never grow.
Eg. you should never do:
if (auto v = dynamic_cast<Dog*>(animal)) { ... }
else if (auto v = dynamic_cast<Cat*>(animal)) { ... }
...
for maintainability and performance reasons, but you can do eg.
for (MenuItem* item: items)
{
if (auto submenu = dynamic_cast<Submenu*>(item))
{
auto items = submenu->items();
draw(context, items, position); // Recursion
...
}
else
{
item->draw_icon();
item->setup_accelerator();
...
}
}
which I've found quite useful in this exact situation: you have one very particular subhierarchy that must be handled separately, this is where dynamic_cast shines. But real world examples are quite rare (the menu example is something I had to deal with).
dynamic_cast is not intended as an alternative to virtual functions.
dynamic_cast has a non-trivial performance overhead (or so I think) since the whole class hierarchy has to be walked through.
dynamic_cast is similar to the 'is' operator of C# and the QueryInterface of good old COM.
So far I have found one real use of dynamic_cast:
(*) You have multiple inheritance and to locate the target of the cast the compiler has to walk the class hierarchy up and down to locate the target (or down and up if you prefer). This means that the target of the cast is in a parallel branch in relation to where the source of the cast is in the hierarchy. I think there is NO other way to do such a cast.
In all other cases, you just use some base class virtual to tell you what type of object you have and ONLY THEN you dynamic_cast it to the target class so you can use some of it's non-virtual functionality. Ideally there should be no non-virtual functionality, but what the heck, we live in the real world.
Doing things like:
if (v = dynamic_cast(...)){} else if (v = dynamic_cast(...)){} else if ...
is a performance waste.
Casting should be avoided when possible, because it is basically saying to the compiler that you know better and it is usually a sign of some weaker design decission.
However, you might come in situations where the abstraction level was a bit too high for 1 or 2 sub-classes, where you have the choice to change your design or solve it by checking the subclass with dynamic_cast and handle it in a seperate branch. The trade-of is between adding extra time and risk now against extra maintenance issues later.
In most situations where you are writing code in which you know the type of the entity you're working with, you just use static_cast as it's more efficient.
Situations where you need dynamic cast typically arrive (in my experience) from lack of foresight in design - typically where the designer fails to provide an enumeration or id that allows you to determine the type later in the code.
For example, I've seen this situation in more than one project already:
You may use a factory where the internal logic decides which derived class the user wants rather than the user explicitly selecting one. That factory, in a perfect world, returns an enumeration which will help you identify the type of returned object, but if it doesn't you may need to test what type of object it gave you with a dynamic_cast.
Your follow-up question would obviously be: Why would you need to know the type of object that you're using in code using a factory?
In a perfect world, you wouldn't - the interface provided by the base class would be sufficient for managing all of the factories' returned objects to all required extents. People don't design perfectly though. For example, if your factory creates abstract connection objects, you may suddenly realize that you need to access the UseSSL flag on your socket connection object, but the factory base doesn't support that and it's not relevant to any of the other classes using the interface. So, maybe you would check to see if you're using that type of derived class in your logic, and cast/set the flag directly if you are.
It's ugly, but it's not a perfect world, and sometimes you don't have time to refactor an imperfect design fully in the real world under work pressure.
The dynamic_cast operator is very useful to me.
I especially use it with the Observer pattern for event management:
#include <vector>
#include <iostream>
using namespace std;
class Subject; class Observer; class Event;
class Event { public: virtual ~Event() {}; };
class Observer { public: virtual void onEvent(Subject& s, const Event& e) = 0; };
class Subject {
private:
vector<Observer*> m_obs;
public:
void attach(Observer& obs) { m_obs.push_back(& obs); }
public:
void notifyEvent(const Event& evt) {
for (vector<Observer*>::iterator it = m_obs.begin(); it != m_obs.end(); it++) {
if (Observer* const obs = *it) {
obs->onEvent(*this, evt);
}
}
}
};
// Define a model with events that contain data.
class MyModel : public Subject {
public:
class Evt1 : public Event { public: int a; string s; };
class Evt2 : public Event { public: float f; };
};
// Define a first service that processes both events with their data.
class MyService1 : public Observer {
public:
virtual void onEvent(Subject& s, const Event& e) {
if (const MyModel::Evt1* const e1 = dynamic_cast<const MyModel::Evt1*>(& e)) {
cout << "Service1 - event Evt1 received: a = " << e1->a << ", s = " << e1->s << endl;
}
if (const MyModel::Evt2* const e2 = dynamic_cast<const MyModel::Evt2*>(& e)) {
cout << "Service1 - event Evt2 received: f = " << e2->f << endl;
}
}
};
// Define a second service that only deals with the second event.
class MyService2 : public Observer {
public:
virtual void onEvent(Subject& s, const Event& e) {
// Nothing to do with Evt1 in Service2
if (const MyModel::Evt2* const e2 = dynamic_cast<const MyModel::Evt2*>(& e)) {
cout << "Service2 - event Evt2 received: f = " << e2->f << endl;
}
}
};
int main(void) {
MyModel m; MyService1 s1; MyService2 s2;
m.attach(s1); m.attach(s2);
MyModel::Evt1 e1; e1.a = 2; e1.s = "two"; m.notifyEvent(e1);
MyModel::Evt2 e2; e2.f = .2f; m.notifyEvent(e2);
}
Contract Programming and RTTI shows how you can use dynamic_cast to allow objects to advertise what interfaces they implement. We used it in my shop to replace a rather opaque metaobject system. Now we can clearly describe the functionality of objects, even if the objects are introduced by a new module several weeks/months after the platform was 'baked' (though of course the contracts need to have been decided on up front).