PDA

View Full Version : Composition VS Inheritance


FEK315
03-18-2011, 05:32 AM
Composition VS Inheritance
Which do Flash professions use more?

Do you use Inheritance with Composition?
Or do you use just Composition?

Thank you :cool:

ASWC
03-18-2011, 12:35 PM
I use both.

FEK315
03-18-2011, 05:26 PM
In what capacity?

wvxvw
03-19-2011, 05:10 PM
Inheritance is the way of darkness, multiplication of not-needed code, excessive complexity, and, most important of all, laziness. On the other hand, composition requires you to do more, it is not rewarding, you will end up rewriting your code again and again due to changed requirements, and you will inevitably fall behind someone who favors inheritance over composition, but you will feel like you've done the right thing--what matters to you more in the end? :)

maskedMan
03-19-2011, 09:22 PM
There's really not a one-size fits all answer to this one. Inheritance + Interfaces I find is often enough to suit my needs when I'm the one writing the code from the ground up, but if I'm relying on 3rd party code, or if I need to shield segments of code in X from changes (radical ones possibly) in code Y then you can use composition to "hide" the direct implementation of Y from X so that world-changing catastrophes in Y don't have such a great effect on X.


Composition is also a great way to allow for "reuse" of code in places where you're expecting code derived from or implementing interface Foo, but you cannot directly plug in that other code because it only derives from and implements Bar (or worse, you're loading it at runtime and have no way to actually make any assumptions at all about the code or its interfaces other than what documentation you may have received on it).

FEK315
03-20-2011, 04:10 PM
wvxvw:LOL, I don't know but it sounds like Inheritance is not "lazzy" at all if you have "multiplication of not-needed code, excessive complexity" That sounds more like lots of work and redundancy. ;) :)

Why would Composition make you feel you did the right? Is it more stable?
What matters to me at this point is that I know how to write solid code that is hard to hack and easy for fellow developers to work with.
I really want to be efficient, economical and fast at what I code.

I guess learning both are extremely important. I understand Inheritance more then I understand Composition at this point. I was reading about how getters and setters are pointless if you just change everything to public but that doesn't sound so safe.

Then I guess Polymorphism and Encapsulation are 2 other ways to structure your program, meaning, can you write a program in 1 of 4 different paradigms?

MaskedMan: Inheritance + Interfaces, could you explain this a little more? Did you mean Inheritance works really well for interfaces like menus?
BTW: If I sound scattered at this point its because everything is really new to me. :eek::confused:

tadster
03-20-2011, 08:23 PM
I'm for Inheritance. Although I don't really define my oop strategy more than keep it simple, and each class should not be more than 200 lines of code.

I can't live without interfaces and mass extensions.
When others need to use my classes, I want them to be able to break all the way down to just what they may need to extend by simply using subclass, and grandchild subclasses... etc...
Or go all the way down to the Interface and implement it all for themselves from the ground up.


I was reading about how getters and setters are pointless if you just change everything to public but that doesn't sound so safe.


getters and setters are way more than alternate public properties.
example, a getter used as a proxy of sorts:

public function get animations():Object {
if (animationGetTimer) {
animationGetTimer.addEventListener(TimerEvent.TIME R_COMPLETE, configureTheImage);
animationGetTimer.start(); }
return _animations;
}


With that system I can get the name of the property that was set on the animations object, eg

animations.runlikemad = [some array of images];
//I get runlikemad to be used dynamically elsewhere


There is no other way to do that without extending the proxy class.

The same system can be used to get the values added to arrays via the push method, using a timer in the getter, gives one just enough time to let the push operation complete, then get the new value that was pushed into the array. Push only invokes the getter not a setter.

wvxvw
03-20-2011, 09:22 PM
Inheritance is about copying over and over again. Composition is about writing only what you really need. When copying and overriding you end up having tons of dead code that doesn't do anything, but it's up the inheritance chain and cannot be deleted. With composition you end up having too many objects, difficult to remember and systematize.
If you want another real-world analogy, inheritance is a Switz army knife, composition is a philips, a player, scissors and a spoon, every one in it's box. You can cook and shave and fix your PC all with a single instrument, but that's hardly the best approach :)

FEK315
03-21-2011, 04:16 PM
"
tadster's Avatar
I'm for Inheritance. Although I don't really define my oop strategy more than keep it simple, and each class should not be more than 200 lines of code."
This sounds like my style Simple. I like efficient and elegant but at this point simple could still get me a job.


I completely understand your analogy, while I would rather work on my car with a set of tools I see how a Swiss army knife would come in handy.

It seems to always come down to do you want it done well or do you just want me to make it work so you can get back on the road.

Thank you for the feed back all.
:cool:

maskedMan
03-21-2011, 04:26 PM
FEK315: When I say "Interface" I'm not referring to a gui, I'm referring to the specific reserved keyword "Interface" in AS3 as well as the concept of an "Interface" in OOP.

For an example of what I mean see this:
http://www.scriptocalypse.com/?p=45

FEK315
03-22-2011, 04:13 PM
Lol!:rolleyes:
figures!

This is cool, Thank you for the link :cool:. This AS3 rabbit hole goes deeper and deeper. :D

Barna Biro
04-14-2011, 10:24 PM
each class should not be more than 200 lines of code
That I find somewhat funny... Did anyone ever take a look at the source code of any of the frameworks you got in touch with? It's easy to say stuff like that when you are creating a circle that rotates senselessly on the stage, but things get a lot more complicated with larger applications.

Not saying you can't go crazy and start breaking even the most minor stuff into classes... but honestly, is anyone that crazy? "Let the class only have 200 lines of code, but be composed of 100 minuscule classes that don't do much and are not likely to ever get reused..." That's the spirit! Not.

Finding the correct balance is an art... Both approaches can have their place.

tadster
04-15-2011, 01:20 AM
Well, Barna, I'm currently making a very complex platformer game (ala mega man, sort of)
not one classes has more than 200 lines of code, except for the main engine of the game...(it has 300) and let's see, in total there has to be at least, meh, 50 or so classes, not including the library on top of which the game is built. Each class does an important job, not one is less than 50 lines of code.

It's just the way I do things, in order to help me organize very large and complex apps.
And, if you think about it, even for one normal-to-complex AS3 app, 200 lines is plenty.


Remember me? I'm the guy who used to write whole games in just one .as file:
http://www.actiontad.com/#spaceshootergame

I've learned a lot since then.

Barna Biro
04-15-2011, 10:19 AM
There's only on thing "fishy" in your reply... You are saying that except the main engine and possibly the library you are using to develop the game, everything is less than 200 lines. Could you maybe tell us what exactly your classes are doing? I might sound picky ( sorry ), but since you already have an engine and library backing up your game, then there might not be much code left to be written ( hence the small classes, that most likely 80% of the time only make calls to existing engine / library implementations ).

Dunno man... but when you are using engines, libraries, frameworks to get stuff done, then things aren't really the same. It's like saying "Ok, I build a really efficient Flex component that does something cool and it only has 100 lines of code!" ( well, yeah, we can just forget that our component is based on a framework and inherits from UIComponent that has 5000+ lines of code!!! - i've kinda came up with that random number because I'm not sure how many of the 13500+ lines of code are actual comments ).

Don't get me wrong now... I'm not disagreeing on the fact that we should keep things clean and well organized. All that I'm saying is that things are a lot more complicated in larger scale applications ( please tell us what library are you using and engine for the game... I'm really curious to see what's behind those things ).

tadster
04-15-2011, 11:10 PM
please tell us what library are you using and engine for the game... I'm really curious to see what's behind those things


I see you have not been to my site lately! The library is my own, the engine is the SimplePlatformEngine (360 lines including comments) from my basicGameObjects library.
I've been working on it for the past 1 1/2 years. Most of the classes in the library have less than 300 lines of code, just about all of them (not including the comments)

The library includes a tweener class which itself is only 231 lines of code, including the comments. (and has only 1 other custom class it uses)
The next release of the library will include a browser based profiler with which one will be able to profile your games, in a web browser. That class, is only 216 lines of code, including the comments.
You just instantiate it, then embed your swf in a browser, and like magic an html div appears below your swf, with profiling options for you to see every function your game is calling.. pretty complex, 216 lines of code, with comments.
All the javascript and html is part of the class, it's what takes up the space, again just 216 lines.


When I see myself using more than 400 lines of code is for things like new data types, by that I mean like a linked list or something "coreish" like that, but for everything else, or things that will be used in heavy inheritance or composition, I like to stick to around 200-300 lines for the sake of readability and ease of going back to it later.

If you look around, at examples and tutorials online, it's actually rare to see classes with more than 400 lines of code...

Even take a look at box2d, there are few classes that pass 400 lines. And they are only the very core classes, like b2World and such.

Barna Biro
04-15-2011, 11:38 PM
I see you have not been to my site lately!
You caught me there... Well man, all that I can say then is CONGRATS! Hope you never lose this good habit!

ASWC
04-16-2011, 12:25 AM
When I see myself using more than 400 lines of code is for things like new data types, by that I mean like a linked list or something "coreish" like that, but for everything else, or things that will be used in heavy inheritance or composition, I like to stick to around 200-300 lines for the sake of readability and ease of going back to it later.Tell me if I'm wrong but it seems that you went from "I write all my code in one .as file and I think that's the way it should be done and I don't see why I should use OOP" to "I use only OOP with max 200 lines per class and I think that's the way it should be done" and all that in about a year. Am I wrong here? I think it's great don't get me wrong but still that makes it a bit hard to take you seriously in a "I think that's the way it should be done" type of discussion.

creynders
04-16-2011, 03:37 PM
I have no idea how many lines of code my classes have, but even 200 sounds pretty much to me. If you stick to SRP you'll find your classes will be pretty small. What people have against having a lot of classes goes beyond me anyway, I'd rather have a ton of classes with clear purposes than some monolithic class doing way too much (and therefore being hard to reuse).
And... I certainly wouldn't use the flex classes as an argument to the contrary, since they are dirty, bloated, inflexible and practically impossible to reuse w/o dragging in 90% of the framework with them. To me they are an example of very bad programming.

maskedMan
04-16-2011, 05:40 PM
Creynders! :)

Wow, it's been forever.

ASWC
04-16-2011, 05:43 PM
isn't it true that every single programmer thinks is the only one doing it right?! :p

tadster
04-16-2011, 06:09 PM
Tell me if I'm wrong but it seems that you went from "I write all my code in one .as file and I think that's the way it should be done and I don't see why I should use OOP" to "I use only OOP with max 200 lines per class and I think that's the way it should be done" and all that in about a year. Am I wrong here? I think it's great don't get me wrong but still that makes it a bit hard to take you seriously in a "I think that's the way it should be done" type of discussion.

Lol! yeah, your a little bit right, except that when I was trying to cram as much code in one .as file, I had little clue what I was doing (coming from AS2/javascript) and definitely did not think that that was really the right way to do things... in fact it's because of looking back on my old work and not being able to make heads or tails of some of it (and a long post by LOD) that I finally realized the full power of OOP. :p

And I never said that I think it was the way it should be done. I only said, it is my OOP strategy.. and it's not a strict one; it's not like I get to line 200 and say, "Oh dear got to delete something." Rather, It's just my own personal basic rule of thumb.

Oh, and.. it's been at least 2 years, since my "one file" days ;)

maskedMan
04-16-2011, 07:35 PM
Oh, and.. it's been at least 2 years, since my "one file" days ;)

How 'bout your "write all your code in notepad" days? :)

wvxvw
04-16-2011, 07:49 PM
Regarding Flex - I think I can recollect this being called "lava flow", that is an anti-pattern in programming, when once making a big mistake the programmer prefers to "just live with it", instead of eradicating it all at once, because eradicating the error seems to be to costly. There are few places where Flex seems to run into dead end trying to fix the flows in design, without fixing flows in design. Bindings and display list management would be two things that stand out the most. There are some minor issues, like states and styles too, but we aren't talking here about Flex problems.

I thought I'd write more about why I think inheritance is bad (compared to composition) because I said nothing about the reason that makes me think so in previous posts, and that would make them look like an objection for the sake of objection.
So, here we go: inheritance is easy to implement, in fact, it's usually as easy as typing two words "extends Whatever" and you will get all the features you needed (and, oh wait, you'll get much more features you never needed! but we'll get to this later), then if, using composition, you would need to, possibly define anew all the methods and properties you just "inherited". But not only that, once you inherit the features you want to override them - this basically means that you had taken something, that was already working and you are changing it! You are violating the first rule of applied programming - if it's working - don't change it! Now, you'd think it won't happen to you, nada, it happened to the best of us, and here are some glaring examples: display objects in Flex, since version 4 simply, unconditionally, throw in addChild(). The addChild() never quite worked in Flex, and it went through several incarnations and added requirements, but, in the end it got so complex and hard to manage, that they just sealed it and told you to use something else. Loader class in flash.display.* package - it also has addChild and removeChild methods that do nothing, or don't do what they are meant to do, and this is again due to inheritance being misused.
Alright you may say, this is unfortunate, but doesn't sound like a big deal to your application, you may learn the particular pitfalls and work around them, but, wait, there're lots of methods and properties some objects dragged from parent classes, while, in fact they never needed to have those. And while sometimes you may pretend like you didn't notice the performance loss, you would certainly notice it once you will want to abstract over a group of classes that originally didn't support this sort of abstraction. To make myself clear, here's a classic example: Loader, URLLoader, Sound, FileReference - all of them may "load", and they have a similar method designed for that, but, you cannot make them implement an ILoader - their load() method, while very similar is not similar enough for the interface. This is often the case with inheritance - it, by the virtue of the language implementation, where names of methods and properties are stings, which, of course, may coincidentally be the same, will sometimes result in problems impossible to solve, unplanned and against all your designs.

So, if I'm to drive any conclusions, and based on my own experience, whenever I have to deal with complex objects, many folds so if their code is closed, or otherwise is not possible to modify, given all other conditions are equal, I would always prefer to do:
public function foo(bar:BaseObject, argument:int):void { ... }
then
class ExtendedClass extends BaseObject {
public override function foo(argument:int):void
{
super.foo(argument);
...
}
yet another benefit is that I will be in complete control of what my code does, I won't depend on what super.foo() was meant to do (what if it throws or return early if certain conditions are met?) etc.
I would extend from my own classes, knowing that I can modify the parents if I find flows in my design, but creating a dependency of this sort to foreign classes seems too expensive to me. Of course, some times I have to compromise, or I'm not given other options (like with events or document class), but other than that, I'd prefer to never extend from DisplayObject family but rather to write classes that manipulate display objects. I wouldn't extend from Socket or EventDispatcher for the same reason - unless I'm going to change the base functionality, which is hardly ever needed, then it seems like a waste to extend from them, using those classes will be probably more bug-less since they, as they have been tested a lot, while my additions will require testing.
Writing GUI in this way first seems a bit odd, but once you get used to it, and you have the "bones" of it working, then you'll see how less buggy and more manageable your application is.

ASWC
04-16-2011, 09:45 PM
You convinced me wvxvw and I will never extend a class again! :p just kidding. I understand where you are getting at but still imo that's just a case where your point make sense or can make sense. For me there's no inheritance vs composition. They are both tools that you the coder can choose to use depending on the situation and that's really how I use them. I could also point out some advantages in inheritance as well like in that case where I had a super class and a bunch of sub classes and I discovered later a tiny code logic flow. Lucky me this was in the super class and once updated all my subclasses were updated as well. I had so many sub classes that I couldn't help thinking: "good thing I used inheritance on that one!"

creynders
04-17-2011, 06:00 AM
Chances are though that had you used composition the problem was solved for all "sub" classes too, once fixed in the "super" class.
But you're entirely right, inheritance is not to be avoided, it's just another tool as well. That's why the rule is to favor composition over inheritance, not: death to inheritance :)
Inheritance has it's place and is essential for some things, for instance many patterns use them: decorator, Null object, visitor, observer, ... however having a long chain of inheritance as with the display list is definitely to be avoided.

@maskedman, yes it's been ages ... I've been lurking at the robotlegs fora far more actually.

Barna Biro
04-17-2011, 12:45 PM
@wvxvw: Quick question: How would you go about adding stuff to the display list more exactly with the approach you have described? If I got it right, you were saying that you'd create ( for example ) a Square class that doesn't extend DisplayObject ( or any other visual elements ), instead it would be composed of a DisplayObject. Ok, I'm guessing you'd draw the square into that DisplayObject, but how'd you go about addChild(squareInstance); ? ( which would obviously throw an error since it doesn't subscribe to the right interface ). Would you define a property and do addChild(squareInstance.content); for example ( where "content" is the reference to the DisplayObject composing you Square ) or some other approach?

wvxvw
04-17-2011, 07:18 PM
Well, imagine DisplayObject is suddenly declared final - how'd you do that? I bet it's still possible ;)
OK, on a more serious note, I'd pass a reference to a "canvas" object, where I'd add children and a reference to child any time I need to add or remove it. I wouldn't really center it around DisplayObject, and, if the task is to draw a square, then, probably, I'd have a method accepting Graphics as an argument and drawing a square into it. It could be even a static method or package-level function for all I care :) Maybe drawing isn't a great example, because Flash cannot save the state of drawing--something you'd probably like to do, when creating a special Square class. But then it's still a question, whether it's alright to save state in the display object, instead, of, say, model (you would probably know this problem from managing item renderers, when, if they happen to have complex content, like checkboxes for example, they, once reused, would retain their state from their previous incarnations regardless of you wanting them to save the checked/unchecked state in connection to the data they used to present). Sorry that previous sentence came out a bit too complicate, but I hope it makes sense :)

Barna Biro
04-18-2011, 10:36 AM
Ok, so what you are saying now is that the second class would be a manager for your "canvas". But that's not what I understood from your previously reply ( probably my bad ) and that wasn't really what I have asked. :) You were talking about composition and how you'd have a class that does not inherit from DisplayObject, instead, it would be composed of a visual object. From what I understand now, when you said "composed", you were actually meaning "it will act as a manager for an existing DisplayObject" ( although your manager class is composed of other objects, I personally don't consider such classes a "good example of composition" ... it's more like "pure proxying" ).

Anyway, thanks for taking the time to reply! Cheers!

wvxvw
04-18-2011, 01:12 PM
Np :) and, besides, just as a real-life example. Due to some difficulties with overriding native flash classes, in HaXe it's rather uncommon to subclass display objects, and even if you do so, you won't be able to override the default behavior. But at some point I discovered I rarely need that.
At the same time I was trying to write a GUI framework, I think it's something any AS beginner programmer will do, just like any PHP beginner will write a CMS of their own :) Besides many other serious problems it had, one was that it was designed to extend from display objects, just like fl.*, mx.* or spark.* (to an extend) etc. This proved to be a bad idea. Some classes would make assumption about features other classes may have, especially bad, if it would happen in the context of display objects, here are few examples:
- the assumption that you may deffer visual properties validation (i.e. position and size) is wrong, because it is possible to use them through transform.matrix and creating a Transform object that targets your display object and then it will bypass setting x/y/width/height/scaleX/scaleY/rotation.
- the assumption that you can reliably tell if a display object is on display list is wrong - it may be a mask, or a hit area, or a state of a SimpleButton.
And it continued and continued until I realized, that, while I don't have the source code for DisplayObject, whenever I override it's properties, I, most probably introduce new bugs, some difficult to find, and some, I may not even found yet. So, in the end, I decided that it is just simpler to assume the DisplayObject is not under my control, and I won't modify anything in how it works, at least I will be dealing with some common denominator, and I won't be held responsible for bugs which came as a result of other people making modifications to DisplayObject's subclasses :)

diplo.monstarr
04-18-2011, 11:49 PM
My .02:

I don't follow the analogy of inheritance being like a swiss army knife. I can go into detail, but honestly I think its an arbitrary disparaging comment.

Also, if you find that you are inheriting a lot of "garbage" useless code as you extend your classes, then maybe you should rethink how you're coding. Its pretty apparent than much of the power of inheritances comes from "lowest common denominator" classifications.

wvxvw
04-19-2011, 12:00 PM
I would be happy if you instead had found the time to go into details, seriously.
Another common place, as I see it, where inheritance becomes a swiss army knife (or the "golden hammer") in AS3 is when designing GUI - the tendency is to extend from display objects. It is in fact rarely needed because display objects, as they are, provide enough functionality and what you really had have done is you had have written the code to manage display objects. A historical example: first classes for programmed animation would "extend" MovieClip (remember AS1/AS2 MotionTween code? - it was all like MovieClip.prototype.move = function() { ... } and so on). Most animation libraries today would have separate classes for computing animation, which never extend MovieClip or any of DisplayObject family.
There is another "historical" reason for inheriting from display object - these are the classes one would learn at the very beginning of learning AS3. Flash IDE also blurs the difference between variables, classes and display objects in the way it manages the timeline code. So, when anyone creates her first coverflow component, she extends it from Sprite, while there was no such requirement, and coverflow component could've operated on a given Sprite[s] instead.

Regarding your other statement, there's something that escaped your attention, I did say that extending my own classes would usually pose less danger of inheriting useless code, then inheriting from the class with the source code I cannot change.

creynders
04-19-2011, 06:27 PM
Ok, so what you are saying now is that the second class would be a manager for your "canvas". But that's not what I understood from your previously reply ( probably my bad ) and that wasn't really what I have asked. :) You were talking about composition and how you'd have a class that does not inherit from DisplayObject, instead, it would be composed of a visual object. From what I understand now, when you said "composed", you were actually meaning "it will act as a manager for an existing DisplayObject" ( although your manager class is composed of other objects, I personally don't consider such classes a "good example of composition" ... it's more like "pure proxying" ).

Anyway, thanks for taking the time to reply! Cheers!

Actually that wouldn't be pure proxying since it doesn't necessarily have (all of) the same functionality (ie. doesn't necessarily expose the same public API) as the display object it's controlling. It's more of a controller or mediator actually. The Loader object is a clear example of a proxy, since it simply extends the behaviour of a display object and literally is a placeholder for the display object it represents.

Barna Biro
04-19-2011, 08:10 PM
Sorry, it was a quite poor word choice from my part... "mediator" was the word I was looking for. Anyway, what matters is that we are all on the same page ( despite my poor word choices and sometimes tangled way of describing things ).

Rhuno
04-21-2011, 11:59 PM
Both have their place in programming. Without inheritance, we'd all be reinventing the wheel over and over and over again. Inheritance avoids redundancy and lends itself to more flexible code. It is both elegant and powerful. If similar objects can use the same variable and methods, then it makes sense to incorporate that behavior into a common class; otherwise you'd end up writing and rewriting the same code for each individual class.

wvxvw
04-22-2011, 06:33 AM
Code reuse is more general idea then inheritance or composition. Inheritance is a tool for reusing the code, composition is just the same - the tool for reusing the code. My point is that in most cases composition achieves the goal while demanding somewhat more work from programmer; inheritance is easier, but may fail sometimes to do the work in the best possible way. One of the problems of composition is that it tends to *reuse* both the code you wanted and the code you didn't want to even use--that's why I say it creates redundancy.

FEK315
04-22-2011, 07:17 PM
This is great!
I know its been a while since I have posted but I have made a lot of progress and you all have helped quite a bit in helping me understand why things work and what is best to use. Thank you!!!!:cool::D:)
I just want to let you all know that I am about 80% finished with my first game.
I got the game completed now, I am working on the loader, starting screen, ending screen. I have stuck too it even though it's been a few nights of I GIVE UP!( yeah for about and hour or until i kept working on it)

Thank you again, you guys are THE BEST!!!!!!

SavedByZero
05-25-2011, 05:23 PM
I think using the "is a", "has a" test is good to determine whether you're using composition or inheritance.

In "AS3 With Design Patterns", Joey Lott lists the propagation of changes from superclasses to subclasses as a disadvantage, but I don't always agree. Sometimes I want that to happen, as it saves a tremendous amount of work. If a manager decides he wants me to change the way all sections of an app fade in and out, and all those sections inherit from a superclass called FadingContent, I make one change to one line of code in the superclass and voila.

Barna Biro
05-27-2011, 07:33 AM
@SavedByZero: not sure if your example is really that good... you could also build your stuff differently, possibly making some use of the Strategy Pattern and have fade strategies that are applied to your components... if your manager wants you to apply a different fade to your components, then you simply write a new fade strategy and apply that instead.

I agree with wvxvw on the part that I also prefer that components don't contain implementation that might not ever be needed ( stuff like that is usually the result of a heavy use of inheritance... you start dragging unneeded mechanisms / methods / properties with you that might not make sense and might just lead to problems on the long run ). What if you would need to have "component groups" that should fade in a certain way and others in different ways? Would you start overriding the specific components ( may those be in quite some numbers )? Also, what if you don't want certain components to fade at all, but you still want them to share the same abstract interface as others... you'd just override the methods responsible for fading and leave them empty?

I'm really not a fan of such approaches... Also, a quite important OOP principle says that objects should be closed for modification but open for extension ( so modifying your base class's fade mechanism directly, isn't a great approach from a theoretical / philosophical point of view at least )

Don't get me wrong now... I'm not saying that inheritance should never be used, sometimes, it actually saves time and it makes sense, but it's healthy to spend some time investigating other possible approaches as well... approaches that might take a bit longer to implement but which might help you end up with a more flexible, reusable and clean solution ( this is quite important in situations where you know that there is a chance that the client / manager will want to change / extend things at a later point in time... like the fade mechanism you have mentioned... ).

SavedByZero
05-27-2011, 02:43 PM
I modified the base class from the base class, not from one of the subclasses. Last I checked, rewriting your own code was allowed in OOP. Defining strategies for fades in this case would add more overhead without any significant benefit.

If I needed all different types of fades from different pages, I probably wouldn't use this. But the policy here is consistency with page transitions.

I agree with diplo.monstarr and Rhuno. There's no reason to assume that subclasses will be inheriting properties they don't need. If you use them responsibly (as I do...most of the time), that won't happen.

creynders
05-28-2011, 08:19 AM
I modified the base class from the base class, not from one of the subclasses. Last I checked, rewriting your own code was allowed in OOP. Defining strategies for fades in this case would add more overhead without any significant benefit.

If I needed all different types of fades from different pages, I probably wouldn't use this. But the policy here is consistency with page transitions.

I agree with diplo.monstarr and Rhuno. There's no reason to assume that subclasses will be inheriting properties they don't need. If you use them responsibly (as I do...most of the time), that won't happen.

The idea of favoring inheritance over composition and actually most of best practices is not getting things done NOW, as fast as possible. It's all about reuse, scalability and portability. If you adhere to proper coding practices you'll see that it will give you a lot more flexibility and less headaches down the road. Sure, in this specific project your fading solution works, why not? The thing is that in the future _if_ for whatever reason you would want to have multiple fading options (because the client asks it for instance) you'll be rewriting again, while if properly setup from the beginning that would not be the case.
Inheritance as used by the majority of programmers leads to a big mess. One very fine example is the UIObject#addChild method in Flex 4, which you're not allowed to call directly anymore. I mean that's not just bad coding, that's just plain ridiculous: having a part of the public API you're not allowed to use! And it's a consequence of having an immense inheritance chain. If they'd done it properly using interfaces and composition they'd never put themselves (and consequently us) into this situation.
Again, inheritance certainly has its place and is necessary, but it should only be used if you can't solve it with composition to begin with. I use inheritance in all of my projects, for very basic base classes, abstract classes etc. I almost never use inheritance with classes that actually DO something, since it will give me lots of troubles when use cases and features necessarily change. And they will change. Clients change their mind, you run into technical impossibilities you couldn't fathom in the beginning, backend services are implemented differently because of all kinds of reasons, et cetera.

wvxvw
05-28-2011, 01:14 PM
I've heard recently an interesting thought. I don't subscribe completely to this point of view, but I think it's worth mentioning here.
So, the idea is that you may not inherit implementation, you may only inherit the "structure". Which means, that you are only allowed to extend an abstract class, but never a concrete class. All concrete classes should be final thus.
This will not prevent situations where you have redundant public API from reoccurring, but, at least, you won't have to "seal" existing functionality.
This potential of inheriting redundant functionality may be solved, using multiple inheritance, but multiple inheritance harbors yet another set of dangers (inheriting the same method from different ancestors, or, even worse, inheriting a method with the same name, but serving different purposes).
Solving it using decorators of sorts or duck typing, which will allow you to "cherrypick" the properties you want to inherit, will, on the other hand compromise object identity. I.e. you won't be able to treat all descendants of an object of a given type the same - they won't guarantee all the properties will be in place.

Maybe, having in general more tools to handle inheritance, or, more generally, code reuse would solve every particular case, but would be also more complicated...

creynders
05-30-2011, 07:27 AM
So, the idea is that you may not inherit implementation, you may only inherit the "structure". Which means, that you are only allowed to extend an abstract class, but never a concrete class. All concrete classes should be final thus.
That's approximately what I meant, but I'm in no way that strict about it, I think. I do sometimes let classes inherit out-of-context implementations and am notably lazy when it comes to proxy or wrapper classes (especially when proxying or wrapping any flash or flex classes), though I've regretted that too every now and then.
Probably it's as with all best practices: adhere to it 99% of the time and if you don't, know what you're doing.

drkstr
06-15-2011, 05:49 AM
So here is a real world example how lazy inheritance can bight you in the ass one day...

We have an XML based document format where each node type in the XML is mapped to some kind of class, that then gets constructed via the factory pattern.

Hey since, the Flex framework has a whole slue of classes that can do all sorts of stuff simply by setting properties on them... why not just extend those classes and map the node types directly to them? BAM! done.

...but wait, it seems these classes have a tendency to use a lot of memory, and are not so good at destroying themselves once the structure has been created... what now?

Encapsulation to the rescue! By encapsulating the view class in a light weight model, we can now create the document structure without having to create the entire view.


Inheritance is one of those OOP features that was intended more to save time rather than build sound software systems. Encapsulation is always a better practice in theory, but is sometimes impractical given certain time restrictions.

FEK315
06-22-2011, 04:39 PM
This thread ended up packed with awesome advice and info:cool: