1

Lets say I have a class Person.

class Person{

    Person(std::string, int);
    void walk();
    void talk();
    void eat();

private:
    int age;
    std::string() name;

};

Now lets say I want to add personality to this person object. How should add this feature to this person?

I was thinking of inheritance

class Persona: public Person{

    void charisma();
    void voice();
    void style();
}; 

or should I use composition?

class Persona{

    void charisma();
    void voice();
    void style();
}; 

class Person{
 .....
private:
    int age;
    std::string name;
    Persona _persona;
};

or should I just add the new feature directly to the class Person, which I really don't want because this will make my class Person big and clumsy.

One thing that I came across was Decorator Pattern but I am still wondering if this pattern is of any help for me.

  • 2
    We can't provide a useful answer unless you tell us what kind of problem domain this is being used for. – whatsisname Dec 28 '16 at 19:06
  • @whatsisname you are right I might have made to question too vague .. – solti Dec 28 '16 at 19:42
  • What does charisma() do? It doesn't return anything. – Vaughn Cato Dec 28 '16 at 20:19
  • With the simple example you've shown here, just giving Person a charisma() is fine. Unless personality traits are going to form a big, complex subsystem, there's no point in doing anything more. – Sean McSomething Dec 28 '16 at 23:19
  • The decorator pattern is useful when you want to keep using the same interface but tweak the implementation. Use if if you want to change or add to what walk or talk do, but it won't help you add new methods. – candied_orange Dec 28 '16 at 23:54
1

This is an almost philosophical question.

If you use inheritance:

  • the instantiations of Persona will be very stereotyped persons. More variety would require more sub-typing, giving you very rigid character traits.
  • the inheritance would not reflect the interdependency between the functions. For example, talk() would not depend on voice() unless you'd override talk(). And style() could depend on walk() but walk() should certainly also depend on style()

If you use composition:

  • You could refine and subclass Persona further and populate it using a factory. Similarly, you could independently subclass Person further. This could allow for a bigger variety of persons more easily than with inheritance.
  • The dependency of talk() on voice() and walk() on style() would be easily implemented. However, there is still no interdependency.

Can the decorator help ? Sure ! A decorator is an alternative to subclassing for extending functionality (see GoF). Combining it with your composition approach, you could further variate the Person. It is very flexible. However, you still refine something by adding responsibility or overriding methods.

If you'd want something more creative, you could inspire your design from a technique commonly used in game coding: make your person a collection of components. Each behavior or property would have its own component. You could then easily add new character traits (e.g. introvert, extrovert). You could then combine dynamically the components (e.g. for talk(), look for the voice component for audio rendering, and look at other character traits to decide on strength (volume) of voice, and length of sentences.

Look also at this answer related to design patterns for game characters and this answer on implementing such a design. You'll find there additional references to this architecture, promoted among others by McShaffry.

If you want another alternative

2

The traditional way of framing this decision is the distinction between "is-a" and "has-a". Is a persona a special type of a person, or is a persona something that a person has? "Is-a" makes inheritance a reasonable starting place, and "has-a" points to composition.

0

You're correct to avoid making Person too "large" in terms of the data that objects of its type will contain.

How you should structure the solution depends in part on whether you intend for all Person objects to have a personality. If you do, I'd strongly favor composition. Otherwise, the Person class is redundant. Inheritance is not the best idea for reducing the complexity of classes.

However, if you want some Person objects to not have a personality, inheritance like you describe is one straightforward approach.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.