Composition

Composition
Composition is a technique by which classes may achieve polymorphic behavior and code reuse by containing other classes that implement the desired functionality instead of through inheritance.

Composition is a relationship between two classes that is based on the aggregation relationship. Composition takes the relationship one step further by ensuring that the containing object is responsible for the lifetime of the object it holds. If Object B is contained within Object A, then Object A is responsible for the creation and destruction of Object B. Unlike aggregation, Object B cannot exist without Object A.
magine you create a Student class that holds information about individual students at a school. One piece of information stored is the student's date of birth. It's held in a GregorianCalendar object
As the student class is responsible for the creation of the GregorianCalendar object it will also be responsible for its destruction (i.e., once the Student object no longer exists neither will the GregorianCalendar object). Therefore the relationship between the two classes is composition because Student has-a GregorianCalendar and it also controls its lifetime. The GreogrianCalender object cannot exist without the Student object.
An implementation of composition over inheritance typically begins with the creation of various interfaces representing the behaviors that the system must exhibit. The use of interfaces allows this technique to support the polymorphic behavior that is so valuable in object-oriented programming. Classes implementing the identified interfaces are built and added to business-domain classes as needed. Thus, system behaviors are realized without inheritance. In fact, business-domain classes may all be base classes without any inheritance at all. Alternative implementation of system behaviors is accomplished by providing another class that implements the desired behavior interface. Any business-domain class that contains a reference to the interface can easily support any implementation of that interface and the choice can even be delayed until run time.
Choosing composition vs. inheritance
Composition is generally used when you want the features of an existing class inside your new class, but not its interface. That is, you embed an object to implement features of your new class, but the user of your new class sees the interface you’ve defined rather than the interface from the original class.To do this, you follow the typical path of embedding private objects of existing classes inside your new class.
Occasionally, however, it makes sense to allow the class user to directly access the composition of your new class, that is, to make the member objects public. The member objects use access control themselves, so this is a safe thing to do and when the user knows you’re assembling a bunch of parts, it makes the interface easier to understand.
/*This program displays how composition is used. Three classes display the hours, minutes, day, month, year, and name pertaining to an event*/
#include< iostream >
#include< string >
using namespace std;
class Time
{ //Time class
public:
Time();
Time(int, int);
void setTime(int, int);
void getTime(int&, int&);
void printTime();
void incrementHours();
void incrementMinutes();
private:
int hr;
int min;
};
class Date
{//Date class
public:
Date();
Date(int, int, int);
void setDate(int, int, int);
void getDate(int&, int&, int&);
void printDate();
private:
int month;
int day;
int year; };
class Event
{//Event class
public:
Event(int hours = 0, int minutes = 0, int m = 1,
int d = 1, int y = 1900, string name = "Christmas");
void setEventData(int hours, int minutes, int m, int d, int y, string name);
void printEventData();
private:
string eventName;
Time eventTime;
Date eventDay;
};
int main()
{//instantiate an object and set data for Christmas
Event object;
object.setEventData(6, 0, 12, 25, 2010, "Christmas");
//print out the data for object
object.printEventData();
//instantiate the second object and set date for the fourth of July
Event object2;
object2.setEventData(1, 15, 7, 4, 2010, "Fourth of July");
//print out the data for the second object
object2.printEventData();
return 0;
}
Time::Time()
{ //default constructor
hr = 0;
min = 0;
}
Time::Time(int hours, int minutes)
{ //class time constructor that accepts parameters
if(0 <= hours && hours < 24)//makes sure hours are valid
hr = hours;
else
hr = 0;
if(0 <= minutes && minutes < 60)//makes sure minutes are valid
min = minutes;
else
min = 0;
}
void Time::setTime(int hours, int minutes)
{ //sets a valid time
if(0 <= hours && hours < 24)
hr = hours;
else
hr = 0;
if(0 <= minutes && minutes < 60)
min = minutes;
else
min = 0;
}
void Time::getTime(int& hours, int& minutes)
{
//returns the hours and minutes
hr = hours;
min = minutes;
}
void Time::printTime()
{
//displays the hours and minutes to the screen
if(hr < 10)
cout << "0";
cout << hr << ":";
if(min < 10)
cout << "0";
cout << min << endl;
}
void Time::incrementHours()
{ //increments hours by one
hr++;
if(hr > 23)
hr = 0;
}
void Time::incrementMinutes()
{ //increments minutes by one
min++;
if(min > 59)
{
min = 0;
incrementHours();
}
}
Date::Date()
{//default constructor
month = 1;
day = 1;
year = 1900;
}
Date::Date(int m, int d, int y)
{//constructor that accepts parameters
if(m >= 1 && m <= 12)//makes sure month is valid
month = m;
else
month = 1;
if(d >= 1 && d <= 31)//makes sure day is valid
day = d;
else
day = 1;
if(y >= 1900 && y <= 2010)//makes sure year is valid
year = y;
else
year = 1900;
}
void Date::setDate(int m, int d, int y)
{//sets a valid date
if(m >= 1 && m <= 12)
month = m;
else
month = 1;
if(d >= 1 && d <= 31)
day = d;
else
day = 1;
if(y >= 1900 && y <= 2010)
year = y;
else
year = 1900;
}
void Date::getDate(int& m, int& d, int& y)
{//returns the month, day and year
month = m;
day = d;
year = y;
}
void Date::printDate()
{//displays the month, day and year to the screen
if(month < 10)
cout << "0";
cout << month << "/";
if(day < 10)
cout << "0";
cout << day << "/";
cout << year;
}
Event::Event(int hours, int minutes, int m, int d, int y, string name)
: eventTime(hours, minutes), eventDay(m, d, y)
{
eventName = name;
}
void Event::setEventData(int hours, int minutes, int m, int d, int y, string name)
{
eventTime.setTime(hours, minutes);
eventDay.setDate(m, d, y);
eventName = name;

}
void Event::printEventData()
{
cout << eventName << " occurs ";
eventDay.printDate();
cout << " at ";
eventTime.printTime();
cout << endl;
}
Composition vs. Inheritance
Inheritance Yields (Slightly) Better Performance:-
1. Composition's method forwarding/delegation will often be slower than inheritance's dynamic binding
2. Composition results in more objects getting instantiated, which can incur a performance cost at allocation, (), and GC time
Composition Yields Better Flexibility:-
1. Interfaces of classes involved in a composition relationship need not be compatible, so it's easier to change the interfaces.
2. Composition allows you to delay creation of back-end objects until (and unless) you need them
3. Composition allows you to change back-end objects throughout the lifetime of the front-end object
4. Composition allows front-end objects to share the same back-end objects
But:
1. Composition's method forwarding/delegation results in more code that has to be written, debugged, and maintained.
2. Easier to add new subclasses than new front-end classes, unless you use composition with interfaces
Describe adding method to superclass that has same name but different semantics as subclass. Also the problem of just inheriting an added method signature that you don't want in the subclass.
Class extension (full-blown inheritance -- interface and implementation) is like strapping on a backpack in which your instances carry around not only their own instance variables and everything they refer to in a graph of objects, but also those of all their superclasses. If you don't own the superclass, owner can change superclss by adding lots of heavy instance data that gets added to your backpack and you don't have a choice but carry it around everywhere. The owner can also add a method to the superclass interface that you don't like in your subclass, but suddently its a part of your interface whether you like it there or not (or, what's the ultimate problem has, the same signature but incompatible semantics as an existing method in your subclass). If the superclass owner adds lots of heavy instance data to the superclass, that owner basically has added all that weight to your subclass instance's backpack. Your subclass instances have no choice but carry that around everywhere they go. (In a composition relationship you could change the back-end object, delay initilization until needed, share same backend amont multiple front-ends, etc...)
Object composition
In computer science, object composition is a way to combine simple objects or data types into more complex ones. Compositions are a critical building block of many basic data structures, including the tagged union, the linked list, and the binary tree, as well as the object used in object-oriented programming.
A real-world example of composition may be seen in the relation of an automobile to its parts, specifically: the automobile 'has or is composed from' objects including steering wheel, seat, gearbox and engine.
When, in a language, objects are typed, types can often be divided into composite and noncomposite types, and composition can be regarded as a relationship between types: an object of a composite type (e.g. car) "has an" object of a simpler type (e.g. wheel).
Composition must be distinguished from subtyping, which is the process of adding detail to a general data type to create a more specific data type. For instance, cars may be a specific type of vehicle: car is a vehicle. Subtyping doesn't describe a relationship between different objects, but instead, says that objects of a type are simultaneously objects of another type.
In programming languages, composite objects are usually expressed by means of references from one object to another; depending on the language, such references may be known as fields, members, properties or attributes, and the resulting composition as a structure, storage record, tuple, user-defined type (UDT), or composite type. Fields are given a unique name so that each one can be distinguished from the others. However, having such references doesn't necessarily mean that an object is a composite. It is only called composite if the objects it refers to are really its parts, i.e. have no independent existence.
Benefits
To favor composition over inheritance is a design principle that gives the design higher flexibility, giving business-domain classes and more stable business domain in the long term.
Initial design is simplified by identifying system object behaviors in separate interfaces instead of creating a hierarchical relationship to distribute behaviors among business-domain classes via inheritance. This approach more easily accommodates future requirements changes that would otherwise require a complete restructuring of business-domain classes in the inheritance model. Additionally, it avoids problems often associated with relatively minor changes to an inheritance-based model that includes several generations of classes.
Drawbacks
One drawback to using composition in place of inheritance is that all of the methods being provided by the composed classes must be implemented in the derived class, even if they are only forwarding methods. In contrast, inheritance does not require all of a base class's methods to be re-implemented within the derived class. Rather, the derived class need only implement (override) the methods having different behavior than the base class methods. This can require significantly less programming effort if the base class contains many methods providing default behavior and only a few of them need to be overridden within the derived class. This drawback can be avoided by using traits or mixins.


Free Web Hosting