Nowadays I often hear about Composition over Inhertance. What's your opinion on this?
I like it for code organization purposes.
There are several pitfalls, though... Check this article out:
I'll give you somewhat ethoterical answer: try both and then try to understand where you suffer more (or less :)).
There are a lot of people with different backgrounds in this thread, and some get along with Inheritance just fine, some think that Composition is better.
From personal experience, I'd favor Composition over Inheritance where possible.
Why "where possible" ? Well, because sometimes you don't have a choice. For example, React asks you to subclass base React.Component class and override methods you're interested in. Or, in Rails application you need to subclass base classes for models, controllers etc.
When you have Inheritance, to figure out where the method is implemented, you have to traverse the hierarchy to find it.
When you have Composition, you need to traverse a flat(or at least flatter) structure to know where to find a method you're looking for.
I can't give you any proofs, but flat structures are usually easier to reason about than nested ones, which Inheritance produces.
I'm sorry in advance if you were just looking for general help, but I think personal experience will be the best teacher and you'll find what works better for you.
OOP has nothing to do with either of terms you have mentioned. OOP is about interfaces. Let me present great example of big system that uses OOP and has nothing to do with composition and inheritance: UNIX filesystem
We have different kind of files in UNIX:
And most of UNIX tools (like cat, head, tail, etc.) will work with either of them without any problem. That is what OOP what it is, sharing common interface between different implementations.
I see two questions 1) Is OOP bad 2) Should Composition be favored over Inheritance (this question assumes that oop is not bad, because both inheritance and composition comes within the context of OOP)
Answer to 1- I hear a lot of kids say that, but i dont see them explaining any thing convincingly. OOP was an improvement over procedural thinking. The real fact is oop is pretty hard to comprehend and oops generally is implemented the way, the dominant developer sees the domain. It takes some effort to understand and learn oops and apply them practically. OOPs is meant for re usability, maintainability ,extensibility at the very least. There is another programming style called functional programming style. Javascript is one where functions are passed around. I think by the time the client side JS frameworks like angular started to prosper, OOPs had become defacto industry standard and ppl attempted to write oops style in JS which is where the problems started evolving
2) On this question. yes composition should be favoured over inheritence. I prefer inheritence for data (property) reuse and composition for behavior encapsulation
Everything in real world can be put into small pieces with properties of its own. A car consists of wheels, engine, seat, metal shell etc. An engine consists of several components. OOP is about looking things at individual components (like wheels + engine + seat + metal shell + etc => car). This is how real world operates, OOP is just that for programming.
A car has wheels so it depends on wheel's properties like friction, pressure in wheel's tube etc. This is inheritance. Composition, as I understand from other comments, is inheriting from several components (wheels, engine etc). It is also OOP. OOPS is used unknowingly in many places and it is not bad. It is a great tool if used in correct way.
This video sums up why you would want to use composition over inheritance quite nicely. https://www.youtube.com/watch?v=wfMtDGfHWpA
Well, since you mentioned that "nowadays there is a hype about the Composition over inheritance" I suppose that you are talking from the frontend and especially JavaScript point of view.
JavaScript never had, doesn't has and will never have a classical OOP, simply, because it is really not needed. JavaScript per design was and still is a simple language. Unfortunately, many people made JS feel too bad and complicated last years.
Answering your question from the JavaScript point of view - yes, OOP in JS is very bad, it was a weak language from the beginning and had an absolutely different design and use-case.
First of all, I (and many other great JS engineers and architects) would recommend avoiding using "class" syntactic sugar in ES6 at all because it only added more complexity and didn't solved any problem, moreover, this new class feature is confusing for people who don't know JS well and it also is very bad implemented, for example, you can't define properties at all, lolwhut, and they called it class, rly? When I need to make some properties readonly, writable, configurable I still need to use Object/prototype syntax, omg. All those "OOP" features in JS were implemented only to make language more popular because there are so many people around the world who don't know the main secret in the software engineering:
Sometimes, the elegant implementation is just a function. Not a method. Not a class. Not a framework. Just a function.
That is also a reason why JS became so complicated last years, just all that backenders and Java-fanboys came into the frontend and they can't imagine that it is absolutely possible to write a whole codebase without a single class.
After working with JS for long time now I also had to train myself and change my mindset. You can't use any language without understanding it and its culture first. You will never become a professional English speaker if you will keep following Chinese languages rules, for example, and vice versa. People also should learn JavaScript only within it's main use-case and environment - browser and Web APIs.
So, simplest approach I (and many others) found is just using Composition over Inheritance, where everything is just a set of pure functions and whenever you need something a bit complicated, you just combine those primitives together. This gives you maximum simplicity and flexibility and I call it a Lego principle. You have a lot of ready small details, just pick ones you need and you are ready-to-go. Apart from the useless "class" syntax ES6 introduced the new most powerful feature of the language - Object.assign()
I wrote an article Vanilla JavaScript Components with different Object.assign() examples and use-cases. Probably, there is no true composition, but you may pass many objects to Object.assign(). For example, you may have simple object which adds accessibility to your component, another simple object deals with attributes, and you now may easily combine them.
const Button = Object.assign({}, AccessibleComponent, UIComponent, EventsComponent, {
...
});
There is also no inheritance because it really introduces only needless complexity and a Gorilla-Banana problem. You may change the original object or you may create a new object and assign to it all the properties and methods of the one or more source objects.
In many OOP languages you also can't do a multi-inheritance, you will have a single instance problem which requires to use a Singleton/Facade pattern, you will need to use "new" a lot, and many other problems you may face.
Pro JavaScript OOP takeaways:
I really very miss now that simplicity and flexibility of JavaScript in the other languages.
However, answering your question from the Software engineering point of view - of course NO, OOP is not about classes, OOP is about good design and primarily SOLID principles and every software engineer should know and follow them.
At the end there is no general solution or style. Combining everything together in a smart way is a best approach.
Deeply nested inheritance can be a real pain to maintain, or even fully understand. It's hard to know the implications of any changes you make to such a system. It leads to a system that's harder to grok. This is probably a system where everything is over abstracted.
One or two levels of inheritance are easy to keep a mental model of, and can be very useful. 16 levels of inheritance mean you will spend most of your time just documenting all those inheritance chains.
Composition is fantastic, but requires everyone manage their resources well. It means the ability to swap out functionality as needed, or lazily create resources when needed. It also means that you might have a complex dependency chain which makes memory leaks a real problem.
I would say they are both completely reasonable to use, and very powerful when used together. The real priorities here are don't over abstract and find ways to simplify the mental model.
In of itself, no, it is not bad. Bad code can be written in any language and any programming paradigm. That being said, I would encourage anyone interested in learning functional programming and functional programming languages to do so.
There are many languages such as F#, Erlang, Haskell, Elixir and Closure that encourage good functional programming practices.
Most modern general purpose languages have functional features. C#, JavaScript and Swift support immutability and higher order functions.
Heyy there, I think you have a missunderstanding right up that question! Inheritance and Composition are basic principles which can apply to OOP :)
Inheritance means, that you have an object, which is derived from another object. Composition means, that you have two or more objects which you mix in order to create a new object. Basically, Composition is the generic form of Inheritance.
Personally, I think we need both, but if both are applicable, prefer Composition.
As for the question "is OOP bad?": No! By all means, OOP is just one way of code architecture. It is not bad per-se. It's more along the lines "use the right tool for the right job." Think of it as: You go on a picknick. Then it starts to rain. Because of that, you will probably say that rain is bad, but on the other side, plants need that rain and for them it is good!
Well, all in all, I like to mix things and use them whenever appropriate, so you will find some FP and OOP in my projects, mixed and happily living next to each other, based on what I need at that certain point :)
Examples of Inheritance and Composition in OOP (JS):
// Inheritance
class Parent {
foo() {};
};
class Child extends Parent {
bar() {};
};
const obj = new Child();
obj.foo(); // ok
obj instanceof Parent; // true
// Composition (simple & stupid)
const Base = {
foo: () => {},
};
const Mixin = {
bar: () => {},
};
const obj = Object.assign({}, Base, Mixin);
obj.foo(); // ok
obj instanceof Base; // false (!!!)
// Composition (correct)
const mx = require('mixwith');
const Base = class {
foo() {};
};
const Mixin = mx.Mixin(superclass => class extends superclass {
bar() {};
});
class MixedClass extends mx.mix(Base).with(Mixin) {};
const obj = new MixedClass();
obj.bar(); // ok
obj instanceof Base; // true
One thing is about OOP and other is composition over inheritance. OOP it's not a bad thing, because there is a lot of languages out there, but I'm agree that is better composition over inheritance, to ensure that a class make one thing and everything that need it's passed by argument or constructor.
This concept is so close to the SOLID principles.
I do stuff on the web
Yury Solovyov
I do stuff on the web
K
Ha!
Todd
Software Security TechLead
The problem with OOP isn't objects or classes, but it is the oriented part. The thing is, there are quite a few applications that do not need to, and are not best designed to be, objected ORIENTED. Not everything is best represented by a class, and it tends to overcomplicate simple solutions at times. An example of this is when you just need to get a few quick things done but you end up having to new up like 5 objects on the heap just to do so. If you've done OOP for any length of time, especially when you had to use someone's library, I know you know exactly what I'm talking about:
var provider = RestaurantIngredientServiceProvider.Create(); Restaurant restaurant = new Restaurant(Location.Texas); IngredientsList ingredientsList = new IngredientsList(provider); MenuItem sandwich = new Sandwich(ingredientsList); sandwich.Make();That kind of thing can be cumbersome; and by the way this example is very contrived; what can I say, it's 2am. But if you really want to see what I mean by this, go check out some of the types on this page. Microsoft in particular seems to be good at throwing all kinds of ridiculous OOP crap around. IMO, this can be an ugly way to solve problems.
Another valid argument that I've heard about OOP is that, by definition it's a little strange - why are we orienting towards objects for? We should be orienting towards solving the problem and I agree wholeheartedly, which is why I prefer object-capable but not necessarily object-oriented approach. It's a feel thing for sure... Best way to get what I'm saying is to write an application using class-city in a language like C# or Java, then go do that in C. C's syntax may be a little more cryptic at first, but the solution is often a lot more elegant and simple. Not to mention, we say OOP has encapsulation, when in reality, it broke the encapsulation that C's header/source system had. Want encapsulation? Just leave the function in the source file and out of the header. Bam, perfect!
As aforementioned, I wouldn't necessarily say one paradigm is "better" than the other overall. Use the right tool for the job. Unfortunately, most people bandwagon to whatever the trend is regardless of the job.