Here is my problem abstracted to Bird
classes. I know that number of Bird
s will increase on the future and new behaviors might be needed. With 10 Birds first design might not look so simple and lead to lots of duplicated code. On the other hand, second design can be perceived as "class explosion". Which of these two designs would be considered best-practice?
Classic:
#include <iostream>
class Bird
{
public:
virtual void Fly() const = 0;
virtual void Speak() const = 0;
};
class Eagle : public Bird
{
public:
virtual void Fly() const
{
std::cout << "Eagle shall fly now!" << std::endl;
}
virtual void Speak() const
{
std::cout << "Eagle speaking!" << std::endl;
}
};
class Penguin : public Bird
{
public:
virtual void Fly() const
{
std::cout << "Penguin shall fly now!" << std::endl;
}
virtual void Speak() const
{
std::cout << "Penquin speaking!" << std::endl;
}
};
int main()
{
std::cout << "..." << std::endl;
Bird* bird = NULL;
bird = new Eagle();
bird->Fly();
bird->Speak();
delete bird; bird = NULL;
bird = new Penguin();
bird->Fly();
bird->Speak();
delete bird; bird = NULL;
return 0;
}
"Better?
#include <iostream>
#include <cassert>
class FlyStyle
{
public:
virtual void Fly() const = 0;
};
class FlyHigh : public FlyStyle
{
virtual void Fly() const
{
std::cout << "Fly high!" << std::endl;
}
};
class NoFly : public FlyStyle
{
virtual void Fly() const
{
std::cout << "No fly!" << std::endl;
}
};
class SpeakStyle
{
public:
virtual void Speak() const = 0;
};
class SpeakLoud : public SpeakStyle
{
virtual void Speak() const
{
std::cout << "Speak LAUD!!!!" << std::endl;
}
};
class NoSpeak : public SpeakStyle
{
virtual void Speak() const
{
std::cout << "No speaking!" << std::endl;
}
};
class SuperBird
{
public:
SuperBird(FlyStyle* fly, SpeakStyle* speak)
: flystyle(fly),
speakstyle(speak)
{
assert(NULL != flystyle);
assert(NULL != speakstyle);
}
~SuperBird() { delete flystyle; delete speakstyle;}
virtual void Fly() const
{
flystyle->Fly();
}
virtual void Speak() const
{
speakstyle->Speak();
}
protected:
FlyStyle* flystyle;
SpeakStyle* speakstyle;
};
class SuperBirdFactory
{
public:
static SuperBird* createEagle()
{
return new SuperBird(new FlyHigh(), new SpeakLoud());
}
static SuperBird* createPenguin()
{
return new SuperBird(new NoFly(), new NoSpeak());
}
};
int main()
{
SuperBird* bird = NULL;
bird = SuperBirdFactory::createEagle();
bird->Fly();
bird->Speak();
delete bird; bird = NULL;
bird = SuperBirdFactory::createPenguin();
bird->Fly();
bird->Speak();
delete bird; bird = NULL;
return 0;
}