Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Is it possible for composition to kick inheritance(super,baseClasses) out of the game in the future?

Discussion in 'General Discussion' started by MapuHoB, Feb 12, 2015.

  1. MapuHoB

    MapuHoB

    Joined:
    Aug 17, 2014
    Posts:
    50
    Recently I showed quite an interest in learning about the composition type of programming. I read many articles where people say inheritance(superclasses) is bad. Not only that is bad but it can be almost fully avoided when using composition. Some references:

    http://blogs.perl.org/users/sid_burn/2014/03/inheritance-is-bad-code-reuse-part-1.html


    http://www.artima.com/intv/gosling3P.html

    https://www.google.bg/search?q=the+fragile+base-class+problem&gws_rd=cr&ei=fCvcVKDVM8z2UuG9hMAB

    http://www.javaworld.com/article/2073649/core-java/why-extends-is-evil.html

    There are many more, similar to these but once you start searching for this problem you will be able to find them without a problem.

    So... do you think more and more programmers will start using the composition designing rather than inheritance(base,superClasses) in the course of time? For sure many of the programmers are already doing it. What do you think are the cons going to be if more and more people start avoiding inheritance? What do we lose so much if we really do stop?


    Unity C# programming approach currently. Well, what about programming with unity? Do you think here the composition approach is to be more worshiped than the inheritance? Should I try every time, when possible, to use composition over inheritance? Many people say in articles, answers and comments that it's not only better but is totally achievable and easier to make changes to longterm as well.

    Please be argumentative in your answers why and why not. If you don't feel like answering all of my questions, to prioritize for now what I need the most is knowing about unity's programming approach.
     
  2. tango209

    tango209

    Joined:
    Feb 23, 2011
    Posts:
    379
    It's a toolbox. No one approach will ALWAYS trump another. Think right-sizing; pick the easiest, most maintainable way to handle a problem. Don't over-engineer; you WILL run into things you didn't think of and boxing yourself in some grand design early usually ends up biting you. I've found it easier to solidify the architecture in the mid to late stages of a project.

    I recently finished cleaning up a simple web application that had FOUR layers you had to get through to get to the database. They were those kind of programmers that read Design Patterns ten times to many. Everything was a pattern to them, damn the size of the project or its maintainability. I cut 6,000 lines of code from its original 10,000 lines. It's faster, easier to maintain, easier to understand, and none of that over engineered crap was ever going to be useful as it was never going to be an application so big or complex that it would have benefited from it.

    Anyways, my two cents worth.
     
    sootie8, Socrates, Ostwind and 4 others like this.
  3. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,500
    This.
     
    zombiegorilla likes this.
  4. R-Lindsay

    R-Lindsay

    Joined:
    Aug 9, 2014
    Posts:
    287
    To be honest your post reads kind of strange. A lot of those links look like click-bait articles.

    Anyway composition and inheritance are ways of expressing relationships (has-a vs is-a). They are simply tools as both posts above me have said.

    Remember why we are using these software tools in the first place; to express a problem domain and then solve/reason about it. So we should really be thinking about that. A. what are the essential relationships in our problem domain? B. how do we express them clearly so that we can reason about them? From this point of view composition, inheritance, interfaces, and so on, are means to an end. We could most certainly employ only one tool from our toolbox and use it to solve all our problems, but when all you have a hammer every problem looks like a nail. I.e. it wont be very elegant, and it isn't being a smart programmer.
     
    zombiegorilla and tango209 like this.
  5. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    You are using Unity right? Then you are forced to build by composition. Each time you are adding a component you are using design by composition.

    Composition and inheritance are by no means exclusive. I typically build a GameObject with a bunch of different components (composition). For examples sake I need an AI, a Steering, an Engine and a Weapon. Each individual component is built by inheritance. There is a Alien AI, Player AI, Aggressive AI and so on.
     
  6. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,500
    It took me a while before I was actually using component oriented design. Before that I was doing the same old inheritance stuff and whacking it in a thing that was attached as a component. That's "using components", but it's not "component oriented design".

    Where it's appropriate, yes. The thing is that both are pretty reasonable solutions to different problems. A problem that a lot of coders have is thinking that one way is "real"/"proper"/"professional"/"superior" and the other is not. In reality they're two of many different, non-exclusive available approaches, all of which have their pros and cons to consider for any given task.
     
    Kiwasi likes this.
  7. MapuHoB

    MapuHoB

    Joined:
    Aug 17, 2014
    Posts:
    50
    For example, in my current project I have smth like:

    public class BasicTime : MonoBehaviour

    public class ShrinkingTime : BasicTime

    public class CustomShrinkingTime : ShrinkingTime

    I have other children of BasicTime as well, but this is only 1 part of them which is totally enough for my question. So, for sure here I'm using inheritance and not only here, on many other places in my project as well. And I have already encountered the inconvinience of having to change smth in the baseClass and to have to modify all the subClasses afterwards which at times can become very annoying. So like many people say most of the class inheritance can be achieved with composition deisgn as well, so how can I do this the compositional way? Also is it worth it and what do I get from it(cons and pros).

    P.S this is just some very simple example, hope it's enough for explanation to my question
    Sometimes it's very hard for me to grasp the ideas of programming here with unity, cause I was used with xna programming style, where I totally used inheritance to its fullest and a little bit of compositioon as well, like class House {Table table; Chair chair;} so on.
     
  8. R-Lindsay

    R-Lindsay

    Joined:
    Aug 9, 2014
    Posts:
    287
    At first glance I would be suspicious of using inheritance in this case, but it would be good to see more. Are you able to provide more of your interface? Method signatures for example. Also are you provide an example of a change to super that broke all your subs?
     
  9. MapuHoB

    MapuHoB

    Joined:
    Aug 17, 2014
    Posts:
    50
    http://pastebin.com/PMY2fm1f

    http://pastebin.com/iqN2TdyV

    http://pastebin.com/8URvQpb7

    I didn't post any further detail because htere are dependecies that I don't have time explaining as you will see in the code here. I'm currently onto doing smth else and don't quite have the time to give further detail about what has happened before. Sounds totally like I'm lazy or it hasn't actually happened but I will risk it, leaving these chunks of code and being misunderstood for the sake of finishing what I'm currently doing.
     
  10. R-Lindsay

    R-Lindsay

    Joined:
    Aug 9, 2014
    Posts:
    287
    Since I don't know anything about your game, including how many classes you have related/deriving from time, take this advice with about a kilogram of salt.

    I'm going to say that a 3 class deep chain for something so trivial is a 'code smell'. AbstractTime and TimeLeft should probably be one class (actually it all could probably be one class) called TimeLeft or TimeManager or something of that nature. BlackScreenGameTime probably isn't a class. You may need to think more carefully about how to provide an interface on one class to manage your different use cases.
     
  11. MapuHoB

    MapuHoB

    Joined:
    Aug 17, 2014
    Posts:
    50
    It's totally not understandable just these 3 scripts. Anyway there are some dependecies that aren't shown in the 3 scripts above. Long story short some games the time starts from 0 to infinity some from 0 to infinity but customized, like stopping at times, or starting at different time, being faster, slower, going backwards, forwards and so on. For example there are games in the project that are with timeLeft type time but without waiting in the beginning for blackscreen to disappear when certain logic is executed. There are some other things here. Anyway, is it going to be better to do this not with inheritance but with composition design or not?
     
  12. R-Lindsay

    R-Lindsay

    Joined:
    Aug 9, 2014
    Posts:
    287
    Honestly it sounds to me like just a singleton class (or single component on your GameManager object) - no inheritance and no composition.
    You have state (start, end, speed, direction) and methods to modify that (pause(), start(), reverse(), etc). And then in your game your logic calls the methods to place it in the right state depending on which path it goes down. Add in some events and listeners and you are done.

    But again, nobody knows your problem like you do, and in the end you only need to satisfy yourself.

    EDIT
    It looks to me like your trying to capture the different time states of your game with each having its own class in inheritance structure. What I am suggesting is that you focus on a class that doesn't know about the specific state of your game, but knows how to manage/expose it. Then to set the particular state of your game mode you simply drive the time manager with values relevant to that game mode my using the exposed properties/methods.
     
    Last edited: Feb 12, 2015
    Kiwasi likes this.
  13. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Hmmm. I haven't read your code, but there seems to be a theme here. Generally you should limit dependency as much as possible. In general you should try to put your dependencies as high up the inheritance chain as possible. I try and tie all of my dependencies to abstract base classes, or to interfaces (interfaces work in really well with the EventSystem introduced in 4.6).

    For something like you describe I would have a data driven design. Use a single class to determine the current state of your game, based on data. Then turn on and off various components based on that state.

    Another generalisation, but a well defined inheritance structure or component structure should not cause changes to propagate through the system. In most cases changing a base class should not necessitate changes in all of its children. If it does you don't have your responsibilities separated correctly, or you don't have your API defined well.
     
  14. MapuHoB

    MapuHoB

    Joined:
    Aug 17, 2014
    Posts:
    50
    Okay, thanks to everybody who gave me hints and advices!