Design dilemma: extensibility vs simplicity Here is my problem abstracted to Bird classes. I know that number of Birds 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 &lt;iostream&gt;

class Bird
{
  public:
    virtual void Fly() const = 0;
    virtual void Speak() const = 0;
};

class Eagle : public Bird
{
  public:
    virtual void Fly() const
    {
      std::cout &lt;&lt; "Eagle shall fly now!" &lt;&lt; std::endl;
    }
    virtual void Speak() const
    {
      std::cout &lt;&lt; "Eagle speaking!" &lt;&lt; std::endl;
    }
};


class Penguin : public Bird
{
  public:
    virtual void Fly() const
    {
      std::cout &lt;&lt; "Penguin shall fly now!" &lt;&lt; std::endl;
    }
    virtual void Speak() const
    {
      std::cout &lt;&lt; "Penquin speaking!" &lt;&lt; std::endl;
    }
};

int main()
{
  std::cout &lt;&lt; "..." &lt;&lt; std::endl;
  Bird* bird = NULL;

  bird = new Eagle();
  bird-&gt;Fly();
  bird-&gt;Speak();
  delete bird; bird = NULL;

  bird = new Penguin();
  bird-&gt;Fly();
  bird-&gt;Speak();
  delete bird; bird = NULL;

  return 0;
}


"Better?

#include &lt;iostream&gt;
#include &lt;cassert&gt;

class FlyStyle
{
  public:
    virtual void Fly() const = 0;
};

class FlyHigh : public FlyStyle
{
  virtual void Fly() const
  {
    std::cout &lt;&lt; "Fly high!" &lt;&lt; std::endl;
  }
};

class NoFly : public FlyStyle
{
  virtual void Fly() const
  {
    std::cout &lt;&lt; "No fly!" &lt;&lt; std::endl;
  }
};

class SpeakStyle
{
  public:
    virtual void Speak() const = 0;
};

class SpeakLoud : public SpeakStyle
{
  virtual void Speak() const
  {
    std::cout &lt;&lt; "Speak LAUD!!!!" &lt;&lt; std::endl;
  }
};

class NoSpeak : public SpeakStyle
{
  virtual void Speak() const
  {
    std::cout &lt;&lt; "No speaking!" &lt;&lt; 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-&gt;Fly();
    }
    virtual void Speak() const
    {
      speakstyle-&gt;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-&gt;Fly();
  bird-&gt;Speak();
  delete bird; bird = NULL;

  bird = SuperBirdFactory::createPenguin();
  bird-&gt;Fly();
  bird-&gt;Speak();
  delete bird; bird = NULL;

  return 0;
}
In my opinion, a better approach (along similar lines) is to avoid abstract base classes and instead use generic "policy" classes. You informally define an interface for each behaviour, and mix them into the class as template parameters. This avoids the need for dynamic memory allocation, and removes the overhead of virtual function calls; everything is resolved at compile time. Your example could be something like this:

#include &lt;iostream&gt;

// Flying styles must have interfaces compatible with this
// struct FlyStyle
// {
//    void Fly() const;
// };

struct FlyHigh
{
  void Fly() const
  {
    std::cout &lt;&lt; "Fly high!" &lt;&lt; std::endl;
  }
};

struct NoFly
{
  void Fly() const
  {
    std::cout &lt;&lt; "No fly!" &lt;&lt; std::endl;
  }
};

// Speaking styles must have interfaces compatible with this
// struct SpeakStyle
// {
//     void Speak() const;
// };

struct SpeakLoud
{
  void Speak() const
  {
    std::cout &lt;&lt; "Speak LAUD!!!!" &lt;&lt; std::endl;
  }
};

struct NoSpeak
{
  void Speak() const
  {
    std::cout &lt;&lt; "No speaking!" &lt;&lt; std::endl;
  }
};

template &lt;class FlyStyle, class SpeakStyle&gt;
class SuperBird
{
  public:
    void Fly() const
    {
      flystyle.Fly();
    }
    void Speak() const
    {
      speakstyle.Speak();
    }
  private:
    FlyStyle flystyle;
    SpeakStyle speakstyle;
};

typedef SuperBird&lt;FlyHigh, SpeakLoud&gt; Eagle;
typedef SuperBird&lt;NoFly, NoSpeak&gt; Penguin;

int main()
{
  Eagle eagle;
  eagle.Fly();
  eagle.Speak();

  Penguin penguin;
  penguin.Fly();
  penguin.Speak();
}