"Is a" vs "Has a" paradigm

This is a discussion on "Is a" vs "Has a" paradigm within the C++ Programming forums, part of the General Programming Boards category; Hi, maybe what I want to ask you guys is pretty common in here. Recently, I've come upon a code ...

  1. #1
    In the Land of Diddly-Doo g4j31a5's Avatar
    Join Date
    Jul 2006
    Posts
    476

    "Is a" vs "Has a" paradigm

    Hi, maybe what I want to ask you guys is pretty common in here. Recently, I've come upon a code of a class which has tons of inheritance like this:

    Code:
    class MainApp: public LayerManager, DisplayManager, SoundManager, AnimationManager
    {
    ...
    }
    So the question is which is better between this "is a" approach with a "has a" Facade pattern approach that encapsulate the classes like this:


    Code:
    class MainApp
    {
    private:
       LayerManager m_LayerManager;
       DisplayManager m_DisplayManager;
       SoundManager m_SoundManager; 
       AnimationManager m_AnimationManager;
    public:
       LayerManager getLayerManager();
       DisplayManager getDisplayManager();
       SoundManager getSoundManager(); 
       AnimationManager getAnimationManager();
    ...
    }
    Just out of curiousity. Thanks in advance.
    ERROR: Brain not found. Please insert a new brain!

    “Do nothing which is of no use.” - Miyamoto Musashi.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,302
    I think that it depends on the situation. Personally, I would rather not use multiple inheritance except to inherit from pure interfaces.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    I agree with laserlight, though there are exceptions imho (not saying that's not what he was saying though). For instance, if you want every public function to be able to be public on MainApp as well, you should probably use inheritance.
    So the real question is, is MainApp basically an interface to all these classes, eg. that it provides functions to use those other classes, or is it really a collection of all those classes?

    Though, really, I can't imagine a MainApp actually *being* a DisplayManager or SoundManager, but rather *use* them.

  4. #4
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Personally I would apply the principles of Software Engineering.

    Just ask yourself, how is a "MainApp" a "DisplayManager"? It seems students at my university often have the same problem. For example given an aeroplane, it's made up of wheels, wings, etc. But a wing is not an aeroplane and an aeroplane isn't a wing. And aeroplanes often have two wings, so how would you do that with inheritance? Same problem with your "MainApp", what if you had two display managers?

    Also, by inheriting from other concrete classes your class is becoming stable. That is, it's very hard to change. Your objective should be a balance between stable classes (i.e. pure virtual classes) and unstable classes (clients of pure virtual classes). This would be the reason why laserlight prefers to use MI only from pure interfaces.

  5. #5
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,274
    Code:
    class MainApp: public LayerManager, DisplayManager, SoundManager, AnimationManager
    Eww.

    First, why is there a class for the main application? Is it so you can instantiate more than one of them? You want two applications running in one application? These things are just pointless singletons. There is nothing wrong with doing something inside main() besides instantiating an object.

    Second, suppose I'm an engineering team lead. I want to take advantage of the skills of the 5 team members working for me. So obviously, I begin by removing my body parts and replacing them with the body parts of my team members so that I am literally composed of all the pieces I need to carry out the work.

    Uh wait... I don't do that, that would be nuts.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  6. #6
    Ex scientia vera
    Join Date
    Sep 2007
    Posts
    478
    Quote Originally Posted by brewbuck View Post
    Code:
    class MainApp: public LayerManager, DisplayManager, SoundManager, AnimationManager
    Second, suppose I'm an engineering team lead. I want to take advantage of the skills of the 5 team members working for me. So obviously, I begin by removing my body parts and replacing them with the body parts of my team members so that I am literally composed of all the pieces I need to carry out the work.

    Uh wait... I don't do that, that would be nuts.
    Hahaha.

    That is without a doubt the best programming-related analogy I have ever heard. I'm going to be forced to steal that one.
    "What's up, Doc?"
    "'Up' is a relative concept. It has no intrinsic value."

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,302
    Well, if I recall a scene from a Transformers movie...
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,598
    I am interested to know where you got the source from.


    Second, suppose I'm an engineering team lead. I want to take advantage of the skills of the 5 team members working for me. So obviously, I begin by removing my body parts and replacing them with the body parts of my team members so that I am literally composed of all the pieces I need to carry out the work.
    Nice analogy, however, it doesn't fit this situation.

    I prefer composition and aggregation over inheritance. I also agree with Laserlight that I only use inheritance to inherit from interfaces. Even though the MS STL is riddled with multiple concrete inheritance I prefer not to do this. In fact it makes me cringe a little when I see it. Of course that is usually only in the STL and when errors in my code cause STL source to open up I quickly close the window and move on.
    Last edited by VirtualAce; 04-08-2010 at 05:38 PM.

  9. #9
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,274
    Quote Originally Posted by Bubba View Post
    Nice analogy, however, it doesn't fit this situation.
    The analogy doesn't fit, or the conclusion drawn from it doesn't fit? Because I was trying to demonstrate the silliness of inheritance in this particular case.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  10. #10
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,598
    I got the part about the silliness of inheritance, however, I mis-understood your comments. When you said take parts of other's and use them as your own I was thinking you were also not advocating aggregation or composition. Misunderstanding on my part. The type of inheritance demonstrated in this post is ugly.

  11. #11
    In the Land of Diddly-Doo g4j31a5's Avatar
    Join Date
    Jul 2006
    Posts
    476
    Quote Originally Posted by laserlight View Post
    I think that it depends on the situation. Personally, I would rather not use multiple inheritance except to inherit from pure interfaces.
    Quote Originally Posted by EVOEx View Post
    I agree with laserlight, though there are exceptions imho (not saying that's not what he was saying though). For instance, if you want every public function to be able to be public on MainApp as well, you should probably use inheritance.
    So the real question is, is MainApp basically an interface to all these classes, eg. that it provides functions to use those other classes, or is it really a collection of all those classes?

    Though, really, I can't imagine a MainApp actually *being* a DisplayManager or SoundManager, but rather *use* them.
    Quote Originally Posted by zacs7 View Post
    Personally I would apply the principles of Software Engineering.

    Just ask yourself, how is a "MainApp" a "DisplayManager"? It seems students at my university often have the same problem. For example given an aeroplane, it's made up of wheels, wings, etc. But a wing is not an aeroplane and an aeroplane isn't a wing. And aeroplanes often have two wings, so how would you do that with inheritance? Same problem with your "MainApp", what if you had two display managers?

    Also, by inheriting from other concrete classes your class is becoming stable. That is, it's very hard to change. Your objective should be a balance between stable classes (i.e. pure virtual classes) and unstable classes (clients of pure virtual classes). This would be the reason why laserlight prefers to use MI only from pure interfaces.
    @laserlight, zacs7 & EVOEx: I agree. That's what I thought too. I don't know what's the reason behind this code. Maybe he needed to make it castable like this:

    "LayerManager* pLayerManager = (LayerManager*) getApplication( );"

    But still, that can be done with a getter function, right?

    Quote Originally Posted by brewbuck View Post
    Code:
    class MainApp: public LayerManager, DisplayManager, SoundManager, AnimationManager
    Eww.

    First, why is there a class for the main application? Is it so you can instantiate more than one of them? You want two applications running in one application? These things are just pointless singletons. There is nothing wrong with doing something inside main() besides instantiating an object.

    Second, suppose I'm an engineering team lead. I want to take advantage of the skills of the 5 team members working for me. So obviously, I begin by removing my body parts and replacing them with the body parts of my team members so that I am literally composed of all the pieces I need to carry out the work.

    Uh wait... I don't do that, that would be nuts.
    Well, yeah. The earlier design was the application can use a CPU for multiple touchscreen for I/O thus multiple instances of the application itself because each touchscreen would be a different independent application. Eg. 1 CPU and 4 touchscreen, etc. But now it's reduced to only 1 but the original code is still not reworked, only the parameter of the display instances is set to 1.

    Quote Originally Posted by IceDane View Post
    Hahaha.

    That is without a doubt the best programming-related analogy I have ever heard. I'm going to be forced to steal that one.
    Quote Originally Posted by laserlight View Post
    Well, if I recall a scene from a Transformers movie...
    Umm... I'm a little slow here. I can't seem to understand the analogy. Can anybody explain it to me? :P

    Quote Originally Posted by Bubba View Post
    I am interested to know where you got the source from.



    Nice analogy, however, it doesn't fit this situation.

    I prefer composition and aggregation over inheritance. I also agree with Laserlight that I only use inheritance to inherit from interfaces. Even though the MS STL is riddled with multiple concrete inheritance I prefer not to do this. In fact it makes me cringe a little when I see it. Of course that is usually only in the STL and when errors in my code cause STL source to open up I quickly close the window and move on.
    Well, it's from a project and the code was from my former lead programmer (he went out of the company a year ago because of a clash with the management). Actually, his code is well structured and well organized. Eg: the LayerManager is used for handling Layers (eg. ModeSelectionLayer, MainLayer, SettingsLayer, PrintingLayer, etc. ) that are pushed inside a stack and will be used to determine the state of the application much like a game state class, all the part of the application are done in dynamically linked library modules so we can re-use the modules to another application if needed, a heavy abuse of void pointers to store different types of data (there's a PropertyBag class that has a hashmap of void pointers which is used for storing lots of things, especially the application's resource. well, I don't know if this is a good practice or not but it makes programming easier.), etc.

    But still, I don't understand his thought about the inheritance.

    Quote Originally Posted by brewbuck View Post
    The analogy doesn't fit, or the conclusion drawn from it doesn't fit? Because I was trying to demonstrate the silliness of inheritance in this particular case.
    Quote Originally Posted by Bubba View Post
    I got the part about the silliness of inheritance, however, I mis-understood your comments. When you said take parts of other's and use them as your own I was thinking you were also not advocating aggregation or composition. Misunderstanding on my part. The type of inheritance demonstrated in this post is ugly.
    ERROR: Brain not found. Please insert a new brain!

    “Do nothing which is of no use.” - Miyamoto Musashi.

  12. #12
    Ex scientia vera
    Join Date
    Sep 2007
    Posts
    478
    Umm... I'm a little slow here. I can't seem to understand the analogy. Can anybody explain it to me? :P
    It may seem he's telling you to not use composition(The has-a relationship), but if you think about it, when you derive from all the classes MainApp derives from, the functions it inherits are literally a part of it, instead of being at its disposal through composition.

    Brewbuck doesn't need his team to be a part of him literally, but rather have their abilities at his disposal.
    "What's up, Doc?"
    "'Up' is a relative concept. It has no intrinsic value."

  13. #13
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Quote Originally Posted by Bubba View Post

    I prefer composition and aggregation over inheritance.
    Speaking of which, the distinction between aggregation and composition has been dropped in UML3.

  14. #14
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,598
    Speaking of which, the distinction between aggregation and composition has been dropped in UML3
    Good. I always get them mixed up and use the wrong type of diamond. Aggregation is an empty diamond and composition is a filled diamond.

  15. #15
    In the Land of Diddly-Doo g4j31a5's Avatar
    Join Date
    Jul 2006
    Posts
    476
    Quote Originally Posted by IceDane View Post
    It may seem he's telling you to not use composition(The has-a relationship), but if you think about it, when you derive from all the classes MainApp derives from, the functions it inherits are literally a part of it, instead of being at its disposal through composition.

    Brewbuck doesn't need his team to be a part of him literally, but rather have their abilities at his disposal.
    OIC. That makes sense.

    Quote Originally Posted by zacs7 View Post
    Speaking of which, the distinction between aggregation and composition has been dropped in UML3.
    Quote Originally Posted by Bubba View Post
    Good. I always get them mixed up and use the wrong type of diamond. Aggregation is an empty diamond and composition is a filled diamond.
    Haha... UML. Now when did I last use it? I'm still like a cowboy coder myself. :P
    ERROR: Brain not found. Please insert a new brain!

    “Do nothing which is of no use.” - Miyamoto Musashi.

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. "has a" vs "is a" relationships
    By carebear in forum C++ Programming
    Replies: 9
    Last Post: 05-03-2006, 02:14 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21