I was asked below object oriented system design question in an interview.
There are multiple devices like Echo show, Echo dot, Echo tab, Smart microwave, Fire tv stick etc.
- Echo show - It has display screen and speaker. It works on electric power supply.
- Echo dot - It has speaker. It works on electric supply.
- Echo tab - It has speaker. It works on battery supply. Battery can be charged.
- Smart microwave - It has screen display. It works on electric supply.
- Fire tv stick - It has speaker. It works on electric supply.
So basically these are 3 categories like - speaker / screen display / both speaker and screen display There are two categories like - electric supply / battery supply. There can be queries on any of these devices like print status. Here are possible outputs for each of this device -
- Echo show - "It is on charging" or "It is not charging" depending on whether it is connected to electric supply or not. This output should come on screen and speaker.
- Echo dot - "It is on charging" or "It is not charging" depending on whether it is connected to electric supply or not. This output should come on speaker.
- Echo tab - "Battery is charging" or "Battery is not charging and battery level is 70%" depending on whether battery is charging or not. This output should come on speaker.
- Smart microwave - "It is on charging" or "It is not charging" depending on whether it is connected to electric supply or not. This output should come on screen.
- Fire tv stick - "It is on charging" or "It is not charging" depending on whether it is connected to electric supply or not. This output should come on speaker.
Assume that there are inbuilt classes for speaking and printing on screen. If we pass string to these class objects they will do respective job.
Now write 4-5 classes to model this scenario.
Design should be extensible meaning if tomorrow any new device comes with a new combination then it can be implemented without creating any new class. So you should not be creating class for each device.
Here is my object oriented solution but interviewer is not happy with it particularly with vector<Output*> outputs
. He was suggesting to use some design pattern instead of vector. Can you think of a better solution?
class Output {
public:
virtual void print(string);
};
class Display : public Output {
DisplayScreen obj;
public:
void print(string str) { obj.print(str); }
};
class Speaker : public Output {
Audio obj;
public:
void print(string str) { obj.print(str); }
};
class PowerSupply {
public :
virtual string get_status();
};
class BatteryPower : PowerSupply {
bool isCharging;
int chargeLevel;
public :
string get_status();
};
class ElectricPower : PowerSupply {
bool isCharging;
public :
string get_status();
};
class Device {
vector<Output*> outputs;//I used vector because Echo show has both display and speaker
PowerSupply powersupply;
Device(vector<Output> &outputs, PowerSupply powersupply) {
this->outputs = outputs;
this->powersupply = powersupply;
}
};
std::vector<Output>
is definitely wrong andstd::vector<Output*>
is ok-ish. I was considering to close the question as duplicate but there is already an answer that imho helps to explain better, so I just dropped the link. – Cladprint(string)
should beconst
. The problem, in my opinion, is that you didn't communicate with the interviewer: "Which pattern did you have in mind?" or "Which specific issue ofvector
should be targeted?". I'm personally not a fan of your justification for usingvector
. Why not makeDevice
templated class with a non-type template parameterstd::size_t kOutputCount
, and a template specialization forDevice<1ULL>
? Also,this->outputs
is avector
ofOutput*
not ofOutput
… Oh. And that constructor isprivate
– Lemmons