Related
It's pretty strange to see all those answers about composition/aggregation/association.
Who/What is the source of those notions?
geeksforgeeks
wikipedia?!?!
stackexchange
and finally my lovely stackoverflow (at least I glad that answers were not marked as verified)
What is the difference between association, aggregation and composition?
What is the difference between aggregation, composition and dependency?
There is a great book "Design Patterns"
GoF
It describes two most common techniques for reusing functionality in object-oriented systems:
1) class inheritance (is-a)
2) object composition (has-a)
"Object composition is an alternative to class inheritance. Here, new functionality is obtained by assembling or composing objects to get more complex functionality."
"Composition" is a very descriptive term to express relationship between objects unlike "Association".
Why all those sources above use term "Composition" in the wrong way?!
Let's go further.
Objects could be composed in two ways:
1) Aggregation
2) Acquaintance
"Consider the distinction between object aggregation and acquaintance and how differently they manifest themselves at compile- and run-times. Aggregation implies that one object owns or is responsible for another object. Generally we speak of an object having or being part of another object. Aggregation implies that an aggregate object and its owner have identical lifetimes."
aggregate object and its owner have identical lifetimes!!!
"Acquaintance implies that an object merely knows of another object. Sometimes acquaintance is called "association" or the "using" relationship. Acquainted objects may request operations of each other, but they aren't responsible for each other. Acquaintance is a weaker relationship than aggregation and suggests much looser coupling between objects."
"It's easy to confuse aggregation and acquaintance, because they are often implemented in the same way. In Smalltalk, all variables are references to other objects. There's no distinction in the programming language between aggregation and acquaintance. In C++, aggregation can be implemented by defining member variables that are real instances, but it's more common to define them as pointers or references to instances. Acquaintance is implemented with pointers and references as well."
Guys, please, help me to figure out what's going on here...
Yes, there is lot of confusion around for these two terms Composition and Aggregation [There is More to add Shared and non-shared Aggregation]. After going through a lot of confusion and getting biased towards UML resources, I have formed my view as follows [need not be taken as final or accurate].
A simplest and loosely coupled relationship I take is Association [it can be unidirectional or bidirectional] where an Object has a reference of other object but both live independently. Association can be Qualified Association if its connected by specific Identity [In OO, identity is an important part of every entity object] e.g. accountNumber for Account of Customer.
Aggregation is collection (of other object types and can be assembled for restricted purpose) maintained by an Object. Still both the objects live independently. e.g. Athletics team. Same student can be part of many such teams like Cycling team [aggregates] and so on. Deleting Athletics team makes no harm to each student entry in college records [they still exist]. Such a relationship can be maintained as Collection of students on Team side or reference of Athletics team for each student being part of team. It depends on more frequently required navigability for application.
Composition is more tight relationship where container object completely holds the contained object and contained object does not have any meaning outside relationship with container object. I can see an example as relationship between Person and Address where for each person we keep separate/ fresh entry of address. For family members Address may have same logical equality, but never physical equality. Change of address for one member does not affect other members [simple test is - DB columns for Person record has extended columns for address as a part of person table.] another example is Single entry (row) of item purchase and Complete bill of items. where deleting bill makes each entry context-less.
If an object instantiates and contains another object completely [never allows outside world to obtain its ref by any means] I would take that as Composition. Techniques like Cloning objects at interaction points instead of passing same ref can be helpful here. In case of association or aggregation, we exchange same reference.
Containment being black-box reuse, is preferred over white-box kind of reuse (implemented using inheritance). Most of the GOF patterns suggest best combinations of Containment for reuse and inheritance for polymorphism. e.g. In case of Adapter pattern, Object Adapter is preferred over Class Adapter.
Implementing all these flavors in Java (Implementations will be language specific) has its own challenge and NOT very straight forward, especially composition. There is a point on learning curve, where one feels (at least I felt) Composition is same as inner class, inner class can help us implement it, but simply having inner class does not give any guarantee of composition.
Recently, i go back to read some parts of the "UML Reference Manual" book, second edition (obviously by: Booch, Rumbaugh, Jacobson).
(see: http://www.amazon.com/Unified-Modeling-Language-Reference-Manual/dp/020130998X)
Meanwhile, i have found these "strange" words in the first chapiter "UML overview" at "Complexity of UML" section:
There is far too much use of generalization at the expense of essential distinctions. The myth that inheritance is always good has been a curse of object orientation from earliest days.
I can't see how this sentence can be fully in line with Object Oriented Paradigm which states that inheritance is a fundamental principle.
Any idea/help please?
You seem to believe the two points are mutually exclusive. They are not. Inheritance is a fundamental and powerful principle of object-oriented programming, and it is overused.
It is overused typically by inexperienced developers who are so captivated with the idea of inheritance that they are more focused on the inheritance tree than solving the problem. They try to factor out as much code as possible to some parent base class so they can just reuse it throughout the tree, and as a result they have a brittle design.
One of the greatest evils of software engineering is tight coupling between classes. That's the sort of thing that causes you to have to work through the weekend after the customer asks for a simple change. Why? Because making a change in one class has an effect on another class, and fixing that class has an effect on another, and so on.
Well, there is no tighter coupling than inheritance.
When you factor too much out to the "top level," every derived class is coupled to it. And as you find more and more code you want to factor out to various levels, you eventually have these deep trees, and every change made at the top cascades throughout the tree. As a result, you start to have methods that return null or are empty. They're unnecessary for the class, but the inheritance contract demands they be there. This violates the Liskov Substitution Principle.
So use inheritance of course. But do it smartly. Favor delegation to inheritance if you have any doubt. And when you do use inheritance, make sure you aren't factoring commonalities to the top level (of the whole tree or a subtree) just to reuse common code, but rather do so because there is a commonality of behavior from top to bottom.
If your tree is more than two or three levels deep (and I think three is really pushing it), you are almost certainly setting yourself up for trouble.
Everything is good in moderation. Remember that the quote is not saying do not use it, or avoid, etc. Rather it is saying it is an overused principal when other OO abstractions or principals work better. Inheritance is powerful but it's coupling is tight.
Wisely or rather randomly the author of the UML book is saying pointing out this current truism that inheritance is often over-used and over-referenced. What about all the other principals and abstractions. I find that developers typically only hit the OO highlights (inheritance being one) and use that abstraction to excess.
For me in UML it is a good reminder that UML is OO generally, but it is not limited to Java or .Net OO features. Many languages only offer of the abstractions available across all languages. UML attempts to help you model and express many of them.
Remember the author only said 'too much use', not bad or incorrect. Also remember that maybe you are an expert developer who does not apply inheritance incorrectly.
I am having a hard time understanding these when it comes to designing a class diagram, from what I know composition is a "has-a" relationship but Aggregation ?? I have no idea what is it. and one thing when will I know to use Composition in a class diagram? and when will I know to use Aggregation in a class diagram?? a example will be highly appreciated.
The main difference between an aggregation and a composition is the property of your "has-a" relationship. It' either strong or weak.
The aggregations "has-a" relationship is of "weak-type". Weak meaning the linked components of the aggregator may survive the aggregations life-cycle or may be accessed in some other way. A simple example would be a football club with its members. If the club is dissolved, you still got the members - which in fact could also be members of other clubs and thus are kept alive.
The composition "has-a" relationship is of "strong-type". Strong meaning that one can't exist without the other. The component's life-cycles are directly linked to the "parent". An example would be a house with rooms. If you decide to tear the house down, you will also lose your rooms.
Maybe a little abstract but I think that's the idea behind it.
See answers to previous questions here, here and here.
Personally I don't use Aggregation. The semantics are too weak to be useful. It causes more problems than it solves. There's only one place where it has well-defined and potentially useful properties that distinguish it from a simple binary association (see footnote).
Composition can be useful because it defines important properties on immutability and lifecycle management (see 1st link above). I've survived quite happily for many years without ever needing to use Aggregation.
hth.
Footnote. Aggregation can be applicable if you need to model a recursive tree relationship, e.g. a part decomposed recursively into sub-parts. Aggregation says there can be no circular relationships, i.e. a part can't be a sub-part of itself - directly or indirectly. However most people reading the model are unlikely to know that. -So you'd need to add a comment. Which means you'd be as well to stick with a binary association and avoid the confusion of using Aggregation.
If you have watched Going Deep shows of the Channel9 lately, one very frequently mentioned topic is mathematical duality in programming. TomasP has a good blog post about duality in object oriented programming.
This has been since Microsoft Research found that the observer design pattern is actually a mathematical dual of the iterator pattern. Since then they have used the duality concept in various ways.
My question is:
What mathematical dualities are there in programming?
Object oriented programming is a good start. The major GoF design patterns are: Decorator, State, Iterator, Facade, Strategy, Proxy, Factory Method, Adapter, Observer, Template Method, Composite, Singleton, Abstract Factory and Command. Here is a good object-graph-poster.
I'd say the primary duality in programming is the code-data duality, most clearly exposed in Lisp, but also clear in most contemporary languages which provide introspection functionality.
Not sure if it is entirely what you were looking for, as it's more FP than OO, but there is of course the Curry-Howard Correspondance (a.k.a. Curry-Howard Isomorphism) that "equates" programs with proofs and types with formulae.
You could argue that the duality of observer/iterator is (sort of, work with me here :-) ) a manifestation of the more general OO paradigms of inheritence and the alternate paradigm of delegation and aggregation. In the former, more specialized objects use base functionality (point up) to inherit general capabilities and in the latter, more generalized objects use delegation to access more specialized functionality (point down/out) - there is much academic discussion about the fact that oo designs can be expressed in either form, and since the variance between forms is (reasonably) rigourous and defined, I'd say it could be classified as a dual
See Treaty of Orlando 2 for more info
I think of objects and closures/anonymous functions as duals.
An object is a bunch of data, with a set of routines that are "attached" to it (i.e. its methods).
A closure, in the functional-programming sense of the word, is a (callable) reference to a function, with a set of data attached (in the form of its bound free variables).
I was once asked in an interview 'What are the 3 main concepts of OOP?'.
I answered by saying that in my opinion there were 4 which are as follows:
Inheritance
Encapsulation
Abstraction
Polymorphism
Was I correct?
There are 3 requirements for a language to be object-oriented:
a language that supports only encapsulation (objects) is not object-oriented, but it is modular
a language that supports just encapsulation (objects) and message-passing (polymorphism) is not object-oriented, but it is object-based
a language that supports encapsulation (objects), message-passing (polymorphism), and inheritance (abstraction), is object-oriented
NOTE: Abstraction is a much more general concept; encapsulation et al are kinds of abstraction, just as a subroutine is a kind of abstraction. See Abstraction
I would say that abstraction is not solely an OOP concept, in that you can abstract to a large degree in many non-OOP languages.
The four pillars are as your correctly state
Encapsulation.
Abstraction
Inheritance
Polymorphism
Encapsulation deals with containing data, nothing more, nothing less.
Abstraction deals with data abstraction, i.e. is all this data really relevant. Think of a bank which contains information on name, age, address, eye colour, favourite tie, etc. Are eye colour and favourite tie really that relevant to the banks requirements? No. This is abstraction.
Inheritance deals with generalisation. Information which can apply to more than one thing. If something inherits from something then it can be said to be a more specific type of that thing. For example, Animal. A Dog is a type of Animal, so Dog inherits from Animal. Jack Russell is a type of Dog, so Jack Russell inherits from Dog.
Polymorphism deals with things having multiple forms, (poly - morph).
Two kinds in programming,
Late Binding,
You refer to something as it's general type and hence the compiler does not know what to bind at compile time. Think method Overriding.
Early Binding
You redefine a method using a different signature, i.e.
int add(int a, int b) vs double add(double a, double b)
These are essentially the basic principles of Object Orientation. There is a lot of overlap between these and so it is quite important to achieve a clear understanding of what each of these mean.
The problem with OOP is that nobody bothered to give a proper, concise, agreed-upon definition. Especially, I'd like to point out that all the aspects you mentioned can well be put into action without the use of object orientation!
Two type systems that do this are the Haskell type system, which, by consense, is generally not regarded to be object-oriented, and C++ templates with template subclassing. However, it could perhaps be argued that template subclassing emulates OOP.
Since template subclassing is not a widely known mechanism, let me give an example from the SeqAn library where it was invented.
String<Char> cstr = "This is a test";
String<Dna, Packed<> > dstr = "GATTACA";
cout << "length(" << cstr << ") = " << length(cstr) << endl;
cout << "length(" << dstr << ") = " << length(dstr) << endl;
Here, String<Char> and String<Dna, Packed<> > are inherited of the “abstract class” String<>. They encapsulate the concept of a string, using completely different methods. They share the polymorphic length method, implemented differently for both concrete types.
Those are the Four Horsemen as I know them. Maybe they mistakenly lump Inheritance and Polymorphism together.
Yes, those are the standard four.
Some people combine abstraction and encapsulation. I'm not sure why... they're not completely orthogonal, but maybe there's enough overlap? There's certainly overlap between inheritance and polymorphism, but it would be hard to combine them, in my mind.
Most people would consider that correct, my guess is if they were asking for three it would be Inheritance, Encapsulation and Polymorphism.
I personally find that those three concepts are the real "meat" if you will behind the definition of OOP. And most people take abstraction for granted and lum it in with the others, as really it could be considered part of any of the other three.
When I talk about OOP though I always mention the 4.
Probably the last three is what they were looking for - inheritance could be argued to be more of a mechanism to help achieve the others, which are higher level goals.
There is not really a correct answer anyway, especially if limited to 'top 3'.
That's correct.
If you had to provide only one, however, Abstraction it's got to be, for, one way or the other, the rest three is merely Abstraction in action.
3 main concepts in OOP:
Late binding
Concept reusing (not sure about this, anyway: re-using of concepts; avoiding the re-implementation of even the simplest concepts)
Abstraction
A proper answer to the question is: "Please clarify what you mean by Object-Oriented Programming." Oops, that would be telling, because the real question being asked is: "When I say OOP, what do I mean?"
There's no correct answer.
OOP
Abstraction (ignoring or hiding details that don't matter) - the situation in which a subject is very general and not based on real situations.
Encapsulation - Keeping properties and methods private onside the class, so they not accessible from outside the class.
! API - is essentially all the methods that are not private, not encapsulated.
Inheritance - Making all properties and methods of a certain class available to child class.
Polymorphism-gr: "many shapes" - a child class can overwrite a method it inherited from a parent class.
This [article][1] refers to the three pillars of good code. I found it to be an excellent article positing that encapsulation is the "first principle" of object-oriented design.
"First" principles are fundamental, underlying principles from which all else springs. The author uses the example of the Golden Rule. It's difficult to teach children all the finer points of civilized behavior but if you can get them to understand (and more importantly, practice) the Golden Rule of treating others as you would like to be treated, then they are more likely to "get" all the legal and moral standards we're held to on a daily basis.
So, it follows that if a developer understands encapsulation as a "First Principle" of object-oriented development, all of the other principles will follow in due course.
I don't do the author's content justice but I would definitely encourage people to read it.
For some reason I'm not showing the hyperlink as coming through so here's the URL: http://www.netobjectives.com/files/Encapsulation_First_Principle_Object_Oriented_Design.pdf
It could have been a trick question for the interview, but in Computer Science classes these days they teach the 4 Pillars of Object Oriented Programming.
It's generally believed that those are the main principles however they had very little to do with why OO was created.
One of the guiding principles was the direct manipulation metaphor. That is creating an object in the program that represented an object from the users mental model. Most of the motivation for creating OO was based in psychology not math/CS as is often believe to be the case these days.
If doubtfull of this take a look at some of the work by Trygve Renskauge. Father of MVC and DCI or James Coplien accomplish author and speaker.
So I'd say you likely gave them an answer close to what they expected whether it's correct depends on where you stand.