Distinguishing between delegation, composition and aggregation (Java OO Design) - java

I am facing a continuing problem distinguishing delegation, composition and aggregation from each other, and identifying the cases where it's the best to use one over the other.
I have consulted a Java OO Analysis and Design book, but my confusion still remains. The main explanation is this:
Delegation: When my object uses another object's functionality as is without changing it.
Composition: My object consists of other objects which in turn cannot exist after my object is destroyed-garbage collected.
Aggregation: My object consists of other objects which can live even after my object is destroyed.
Is it possible to have a few simple examples demonstrating each case, and the reasoning behind them? How else can these examples be demonstrated other than my object simply having a reference to another object(s)?

Delegation
public class A {
private B b = new B();
public void methodA() {
b.methodB();
}
}
When clients of A call methodA, class A delegates the call to B's methodB.
Rationale. Class A exposes behaviours that belong elsewhere. This can happen in single-inheritance languages where class A inherits from one class, but its clients need behaviours that are implemented in a different class. Further study.
Hybrid Delegation
public class A {
private B b = new B();
public void methodA() {
b.methodB( this );
}
}
The difference between delegation that involves simple forwarding and delegation that acts as a substitute for inheritance is that the callee must accept a parameter of the caller, exemplified as:
b.methodB( this );
Rationale. Allows class B instances to use functionality available from class A, just as class B would if it inherited from class A--but without inheritance. Further study.
Composition
public class A {
private B b = new B();
public A() {
}
}
Once no more references to a particular instance of class A exist, its instance of class B is destroyed.
Rationale. Allows classes to define behaviours and attributes in a modular fashion. Further study.
Aggregation
public class A {
private B b;
public A( B b ) {
this.b = b;
}
}
public class C {
private B b = new B();
public C() {
A a = new A( this.b );
}
}
Once there are no more references to a particular instance of class A, its instance of class B will not be destroyed. In this example, both A and C must be garbage collected before B will be destroyed.
Rationale. Allows instances to reuse objects. Further study.
Demonstration Without References
The names given to these simple patterns are defined by their referential relationships.

Your object would reference another object(s) in all three cases. The difference lies in behavior and / or lifecycle of referenced objects. Some examples:
Composition: House contains one or more rooms. Room's lifetime is controlled by House as Room will not exist without House.
Aggregation: Toy house built from blocks. You can disassemble it but blocks will remain.
Delegation: Your boss asked you to get him a coffee, you've had an intern do it for you instead. Delegation is not a type of association (like composition / aggregation are). The latter two have been discussed on Stack Overflow many times
In the comment you ask how the implementation would differ in each case, observing that in all cases we invoke methods on the releated objects. It's true that in each case we would have code such as
myRoom.doWork();
myBlock.doWork();
myMinion.doWork();
but the differences lie in the life-cycle and cardinality of the related objects.
For the Component, the Rooms come into existence when the House is created. So we might create them in the constructor of the House.
In the case of Association (I'll use Tyre and Car) Cars might add Tyres in their constructor, but later you may want to remove and change tyres. So you also have methods such as
removeTyre(FrontLeft)
addNewTyre(aTyre, BackRight)
And it's quite likely that the aTyre object came from a Factory - we didn't new it in any of the Car's methods.
In the case of Delegation, you might not even have a member variable to hold the delegate
resourcingPool().getIntern().getCoffee(SkinnyLatte, workstation 7);
the relationship between the objects lasts only as long as the intern is fetching the coffee. Then it returns to the resource pool.

Your book explains quite good so let me elaborate and provide you some examples.
delegation: When my object uses another object's functionality as is without changing it.
Sometime a class may logically need to be big. But big class is not a good coding pratice. Also sometime, some functionalities of a class may be implementable in more than one way and you may want to change that some time.
class FeatureHolder {
void feature() {
// Big implementation of the feature that you dont want to put in the class Big
}
}
class Big {
private FeatureHolder FH = new FeatureHolder();
void feature() {
// Delegate to FeatureHolder.
FH.feature();
}
//.. Other features
}
From the above example, Big.feature() call feature of FH as is without changing it. This way, the class Big does not need to contain the implementation of the feature (separation of labour). Also, feature() can implement differently by other class like "NewFeatureHolder" and Big may choose to use the new feature holder instead.
composition: My object consists of other objects which in turn cannot exist after my object is destryed-garbage collected.
aggregation: My object consists of other objects which can live even after my object is destroyed.
Technially, Composition is "part of" and Aggregation is "refer to" relationship. Your arms are part of you. If you no longer live, your arm will die too. Your cloth is not part of you but you have them; as you can guest, your cloth does not go with you.
In programming, some objects are part of another object and they have no logical meaning without it. For example, a button is composed into a window frame. If a frame is closed, the button has no reason to be around anymore (Composition). A button may have reference to a database (like to refreash data); when the button is eliminated, the database may still be around (Aggregation).
Sorry for my English, Hope this helps

1) Delegation: Man-driver-car example. A Man bought a car. But that man does not know to drive the car. So he will appoint a driver who knows driving a car. So the Man class wants to perform a transportation using car. But it does not have the interacting- functionality/compatibility with car. So he uses a class which has compatibility with car that is driver which is compatible with man class. Assuming that driver can understand what man says
2) Composition: Car simulation is a routine example. To make a car move, wheel rotates. Car class using wheel class rotate functinality as part of its move function, where as wheel is part of car.
3) Aggregation: Car and its colour. Car class object ferrari will have a colour class object red. But colour class object red can be there as individual class, when user search happens with a specification of red colour.

In a very simple sentence I can say:
Delegation is: delegate behaviour to other class when you do not want to change it. by change I mean during run time. for example you delegate driver to car class that driver wont change while driving.
Composition is: when you want to use behaviour of family of classes (one or more classes, that implements an interface) that you might change during run time. but you should consider these classes can not exist with out main classes, such as rooms of a hotel. If you remove hotel all rooms of hotel will not exist.
Aggregation is: same as composition but classes can exist without main class.

Related

composition relationship in class diagram can have cycles?

I want to implement a model checker for Java class diagrams.
There are many constraints that I've been considered for a while.
Hope anyone can help me figure it out.
All the cycles here I mean are pure cycles with only one type of relationship.
Q1: Suppose class A is composed of class B, is it possible that class B is also composed of class A, given that class A and class B are different classes? Moreover, is it possible for composition relationship to have cycles?
Q2: What about other relationship in the class diagram, like aggregation, dependence and association? What's the meaning of cycles in these relationships? Can anyone give some examples?
Thanks for reading my question and hope someone can help me out.
Q1: Suppose class A is composed of class B, is it possible that class
B is also composed of class A, given that class A and class B are
different classes? Moreover, is it possible for composition
relationship to have cycles?
Strictly speaking in UML terms... yes, but you'd be hard pressed to actually implement this in code. If you ask yourself, "can B stand alone without A?" and "can A stand alone without B?" If you can answer no to both of those at the same time, then you can have two classes composed of each other. Since one would have to be able to stand on its own for the other to be composed of it, you can't have both. However, since composition vs aggregation is largely based on design and context, it's not completely impossible. You can for instance, have something like this:
Class B contains a reference to A, and A contains a reference to B
public class A {
B myB;
String name = "A";
public A(int num) {
this.name += num;
}
public void setMyB(B b) {
this.myB = b;
}
public B getMyB() {
return this.myB;
}
public String getName() {
return this.name;
}
}
public class B {
A myA;
String name = "B";
public B(int num) {
this.name += num;
myA = new A(num);
}
public A getMyA() {
return this.myA;
}
public String getName() {
return this.name;
}
}
In this example, we provide an identifier for the class using a defined String and then append a number to it, just to show some unique ID.
We provide methods that allow us to access both A and B references, but only B creates its reference to the other via the constructor (composition).
Using this simple test:
public class Test {
public static void main(String[] args) {
A myA = new A(1);
B myB = new B(2);
B anotherB = new B(3);
myA.setMyB(anotherB);
System.out.println("A = " + myA.getName());
System.out.println("A's B = " + myA.getMyB().getName());
System.out.println("B = " + myB.getName());
System.out.println("B'a A = " + myB.getMyA().getName());
}
}
We can see the following output
A = A1
A's B = B3
B = B2
B'a A = A2
In this example, the B reference in A is created outside the context of A and passed in as an argument. If we deleted myB, we'd lose the reference to its A, but not if we deleted myA (we still have anotherB.
Suppose we eliminated the setMyB() method from A and moved it to the constructor... we'd have an infinite loop of new objects and you'd end up with a StackOverflowError
You could probably get creative and try to implement the Singleton pattern or some other construct that limits the number of objects created, but doing so would mean the constructors would need to be private/hidden, which prevents extension by other classes. Use of a static field to track number of creations might prevent the error, but then you'd lose all the references without having a place to keep track of them all, and lastly, you'd never have a "perfect" composition, because one class would be missing its component.
After all this "analysis" you'd end up coming up with a design that makes sense, not one that strictly fits what's drawn on a UML diagram. The UML diagram is there to convey "relationships" between classes. The "unique" case you've asked about here where A uses B and B uses A is probably not going to be solved with UML modeling, but probably needs some other design work.
Q2: What about other relationship in the class diagram, like
aggregation, dependence and association? What's the meaning of cycles
in these relationships? Can anyone give some examples?
Association relationships are really used to describe the type of relationships that are defined by composition, aggregation, many-to-many, one-to-one etc, and depend on the context. The meaning of cycles in every association is going to depend on your design.
In general, a cycle in a dependency means that the class depends on itself. This could be for recursive function calling, Singleton design pattern implementation, or some other design pattern requiring a class to refer to itself.
Aggregation was sort of already answered above. It basically means the object "uses" whatever it's aggregating. An example is a Company aggregates People. When the company goes away, the people still exist. A cycle in that kind of relationship is similar to what was shown in my example, except you'd have external references to both A and B classes that were passed as arguments to the first two references to A and B.
The bottom line is... UML is a tool to show relationships between classes. The design and implementation will follow from that and the fact that you have "interesting" relationships modeled with UML will not help you get past serious design roadblocks.
Hopefully this helps shed some light on your questions.

Why not override instead of using abstract class?

This might be a simple question for many but has confused me. I am picking an example from Kathy Sierra that shows the utility of Abstract Classes but I am unable to understand the overall importance of abstract classes.
Example
We have an abstract class Car with abstract methods - power() & topSpeed(). These methods are implemented in sub classes BMW, Volkswagen and Audi.
My question is - why do we need to have the abstract class Car in the first place to customize methods for each car type? Why not have these two methods in any one of these car subtypes, say BMW and then other two - Volkswagen and Audi - can simply override these methods?
By making a method abstract, it means that people have to implement it. You require people to do so and it is impossible for people to forget to do so, as it will fail to compile if they do.
The #override annotation exists for a very similar reason, by marking a method as #override you get an error if (for example) you typed the method name wrong and aren't actually overriding something.
In many ways the abstract class is half way between an interface and a normal class - it defines what you need to do to use it in the same way an interface does, but it also handles some of the implementation for you.
Classes can only extend one other class. They can implement any number of interfaces.
For example you might have MotorVehicle inherited by Car, Motorbike and Train - but then you might have a Steerable interface implemented by Car, Motorbike and Pedalbike.
To answer the question in the comments:
If there is an Interface "I" having method m() which is implemented by class "A" and another class "B" wants to access the method m(), what is the need of interface here. Can we simply not implement that method in class A?
You can - but if on the other hand class B wants to access the method m() in both a class A and class C (where A and C don't inherit from each other or a common class containing m()) then the way to do that is to specify a common interface I and class B uses the interface type, I, not the types A and C at all.
Also remember that interfaces can be used between packages and libraries. For example Listener and Strategy patterns make heavy use of interfaces. When the Java developers wrote JButton (for example) the ActionLstener is specified as an Interface to provide maximum flexibility to people using JButtons in the future.
Why not have these two methods in any one of these car subtypes, say BMW and then other two - Volkswagen and Audi - can simply override these methods?
Wouldn't that require Volkswagen and Audi to inherit from BMW? That wouldn't be correct, since those aren't BMWs.
The abstract base class and its abstract methods form a kind of contract which inheriting objects must implement. There's no such thing as a concrete Car that isn't a more specific type. But all concrete types share commonalities. The abstract Car enforces those commonalities, allowing specific types to be treated as generic instances of Car when needed.
For example, if you have code which needs a Car on which it will invoke the Drive() method, that code doesn't care what kind of Car it gets. It will Drive() any Car. So it accepts an abstract type so that anything which implements that type can be used:
UseACar(Car car)
{
car.Drive();
}
// elsewhere
BMW myCar = new BMW();
UseACar(myCar);
Without this enforcement of the contract, a statically-typed and compiled language would have no way of guaranteeing that .Drive() exists on the object. You'd need to create a UseAX() method for every possible kind of car, each accepting a different type. Using polymorphism like this allows you to create a single, more generic method which works on any instance of the abstract type.
So that you can write code that deals with Cars without knowing what kind of car it is:
public void PrintTopSpeed(Car car)
{
System.out.println("This car's top speed is " + car.topSpeed());
}
If the Car class didn't define topSpeed(), this code wouldn't compile. You'd have to have a different version of this print function for each of your BMW, Volkswagen, Audi, etc. derived classes. This is perhaps the most basic concept in object-oriented programming, so you really need to master it. Base classes allow objects to share common behavior, and allow code to be written to use that behavior without any knowledge of what specific type of object it's dealing with.
Polymorphism is the answer. If you don't have methods power() and topSpeed() in the abstract class you can't do things like this :
List<Car> cars;
cars.add(new Porshe());
cars.add(new Ford());
for(Car car : cars){
System.out.println(car.topSpeed());
}
You would have to handle lot of thing your self if you have only custom methods in your subclasses.
This is called abstraction. Methods in abstract class are considered as protocol so that car makers should not violate.
abstraction is great when the original programmer/architect want's to allow customized behavior to some base class and ensure that the consuming programmer implements the required methods.

How to draw a UML diagram when class A has aggregation and composition relationship with class B?

I have two questions to ask. So let's assume there's a class A and B which are defined like these.
1.
class A {
private B b;
private B otherB;
public A(B otherB)
{
this.otherB = otherB;
}
}
class B {
}
So class A has a composition relationship with the variable b and aggregation relationship with the variable otherB. How can I draw this in UML diagram.
2.Would the following case be still a composition relationship?
class A
{
private B b;
public B getMethod(){
B newB = new B();
newB.bValue = b.bValue;
return newB;
}
}
class B
{
private int bValue;
}
As other comments/replies have pointed out, there is not problem of having different associations (composed or not) between the same classes.
From the implementation point of view (and this also applies to the previous question) you need to understand what a composition association means.
Basically, if we have instance specification a1 and a2 (as instances of the class A), only one of them could compose an instance b1 (as instance of the class B) via the role (association end) "composesB" of the composite association.
Likewise, provided that a1 composes b1 via the "composesB" role of a composite association, everytime a1 gets "destroyed", b1 should also be "destroyed". Instead, this wouldn´t occur if a1 object aggregated b1 via the "aggregatesB" role of an aggregate association.
As you may imagine, from an implementation point of view, you need much more than a field and a simple method in a class in order to support a composite association between two classes.
Update: to include an example.
For example, EMF is an implementation of the EMOF specification (it´s not UML) in which the concept of a containment reference (similar to the concept of a composite association) can be depicted as follows. In our particular case:
Going away from technical details, you may grasp that when you set a B instance as part (contained, composed) by an A instance object. You firstly have to check that the former might be contained in a different A instance via the same containment reference, if so, such B instance needs to be removed from the old A instance one.
Creating Multiple Associations Between Classes is, in fact, legal. The recommendation is to assign a role to each relationship when you do so.
I'm going to say yes, that is still a composition relationship (though others may disagree). To make my case, we look at the simple IBM definition showing Student composed of Schedule (presumably amongst other things). It's very easy to imagine that there would also be a Teacher composed of Schedule, and that a Teacher might want to get the Schedule of a Student, or vice versa. Does the getting of a Schedule by another class invalidate the composition relationship? I think not; or at least, the IBM definition does not appear to be so narrow as to preclude that possibility.

Java combine parents of two large inheritance chains

I have two parent classes in a huge project, let's say ClassA and ClassB. Each class has many subclasses, which in turn have many subclasses, which in turn have many subclasses, etc.
My task is to "marry" these two "families" so that both inherit from a SINGLE parent. I need to essentially make ClassA and ClassB one class (parent) to both of their combined subclasses (children).
ClassA and ClassB both currently implement Serializable.
I am currently trying to make both inheritance chains inherit from ClassA, and then copy all functions and data members from ClassB into ClassA. This is tedious, and I think a terrible solution.
What would be the CORRECT way to solve this problem?
EDIT - some clarification
ClassA and ClassB essentially do the same thing (many calls to many Stored procs, through a series of many classes and method calls of course).
ClassA, however, makes the calls to half of the Stored Procs via a new service based (Jersey) architecture we implemented. I am essentially implementing the new service oriented functionality into "FamilyB" in the same way we it has already been done in "FamilyA". The problem is that each of these families are huge - many classes and long inheritance chains, making small changes has a butterfly effect on the inheritance chains.
If clarification is needed, please let me know.
The first answer that comes to mind is "In general, no".
In order for this to be reasonable, A and B should be special cases of some other thing -- although that is feasible, it would seem unlikely.
Besides that, I don't see any reason to combine any code (and a lot of reasons not to). Is there some reason you cannot simply have both of them extend X, and leave all their code where it is?
I don't think I have enough information for a clear picture yet, but will go with what I have so far.
If you implement a Class X that both Class A and Class B extend, that changes nothing about any subclasses or any use of either class or any subclass. That is certainly where I'd start.
public Class X implements Serializable {}
public Class A extends X implements Serializable
{
// retain all current code to start
}
public Class B extends X implements Serializable
{
// and here be all current code also
}
You say you are currently thinking of merging Class B into Class A; this sounds problematic; A and B share 'about half' of their code and both have a large inheritance tree below them - something that instantiates a Class A subclass could have its behavior changed by having A get some new functionality.
So instead I would move things slowly from A to X and from B to X. I would try to move things only if they had commonality between the A and B trees.
For instance, let's say you have method abc() in A and def() in B with the same functionality. You could move this functionality to X and call it anything you want - I would probably try to give it the name I thought best described its function, whether that came from A, B, or I made up a new one. Then abc() and def() could invoke this new function, and the code for these methods could be removed from both of them.
public class X implements Serializable
{
public void abcdef()
{
// common functionality, merged from A and B
}
}
public class A extends X implements Serializable
{
public function abc() { abcdef(); }
}
public class B extends X implements Serializable
{
public function edf() { abcdef(); }
}
One good thing about proceeding this way is that it is clear at each step what has been done. You could mark it well with comments and have it reviewed, and/or put it through tests to insure that functionality of both the refactored methods was complete and correct; this could be done after one, two, or more methods were refactored, depending on whether you have good setups for review and/or testing.
The only case where this might break is if, for some reason, you want the callers of methods in the two inheritance trees to change, but I don't have any reason (yet) to think that is necessary. Hopefully all the methods have at least reasonable names describing what they do and passing the parameters that need passing, and the refactoring at the top only affects the implementations, not the calls. It looks like a big enough job anyway, I'm hoping you don't have to change the calls as well as the functions.
My instinct is to create a new class that has objects of ClassA and ClassB as members, then use that as the base class for the things that you essentially want to derive from both ClassA and ClassB. For example:
class ClassAB
{
private ClassA a;
private ClassB b;
public void doSomething()
{
a.doSomething();
}
public void doSomethingElse()
{
b.doSomethingElse();
}
...
}
Sure, it's tedious, but it seems a lot easier and a lot less likely to lead to bugs than trying to rework ClassA and ClassB to make this possible. Does that work in this case?
Why don't you create a new class that ClassA and ClassB both extend and then start merging shared functionality up there.
Be sure that it actually makes sense to merge the code from ClassA and ClassB though.

General programming question about scope

This is more of a general programming question so the code examples I give will just be pseudo-code. I program in C++, Java, and Python so the pseudo-code is a mix of those. I am not too sure what the name of this is called so if you could give me a name for this, I can Google for more information about it I would greatly appreciate it.
Let's say I have a class called A. In this class, I create an instance of a class called B:
class A {
//instance variables
classB;
variable1;
variable2;
//instance methods
instanceFunction(parameter1, parameter2) {
//Do Stuff
}
function1(parameter1) {
classB = new B(some parameters);
}
setVariable1(value) {
variable1 = value;
}
getVariable2() {
return variable2;
}
}
In class B, I want to make changes to or make use of instance variables in class A. I can do this by passing a reference to A into B. So my A::function1 would look like this:
function1(parameter1) {
variable1 = new B(this, other parameters);
//Python syntax:
//variable1 = B(self, other parameters)
}
and my class B would look like this:
class B {
//instance variables
parentClass;
variable2;
//instance methods
instanceFunction(classA, other parameters) {
parentClass = classA;
}
function1() {
parentClass.setVariable1(someValue);
}
function2() {
variable2 = parentClass.getVariable2();
}
}
What other ways are there to have use of the variables in class A inside of class B?
If the code was C++ or Java, assume all variables are private and all methods and functions are public. Also assume all variables are passed by references or a pointers.
Edit:
First, thanks for all the responses!
Some clarification:
The reason I am asking this question is I have done a good amount of Qt programming in C++ and Python. In Qt, there are signals and slots. This lets inner objects tell the outer object to do something. For example I have an object A with objects B and C inside of it. Some change happens to object B and B needs to let A and C know. So B will emit a signal. A will catch this signal and do what it needs to do. Then, A will also let C know that B emitted this signal. This way C can do what it needs to do.
The reason I asked my question is because I was wondering how I can do something like I described without using the Qt libraries.
Also, let's assume B "is not" an A so I can't/don't want to use inheritance.
I am not too sure what the name of this is called...
I am having trouble following your pseudo-code, but you might be able to accomplish what you're looking for via:
Inheritance, which allows derived classes to access protected variables from a base class (static or instance variables)
Friend functions (C++) (which allows functions to have access to private instance variables on a class)
Dependency Injection (But probably only if you have more complex requirements than you're actually stating in your question. In this super-simple case, you'd just be accessing public properties or fields when an instance is passed in to a function - you might have to access them through a public getter/setter, since you want the variables to be private)
Edit:
After your edits, it is pretty clear that you want the Observer Design Pattern. This allows you to decouple the code that responds to a state change from the code that signals the state change.
That pattern is less about access to variables (as my first links were about), than it is about responding to events (or "state transitions", if you think about your class as a Finite State Machine).
Given the edit you made; It may be practical to implement a sig/slot mechanism using boost::signals, or the threadsafe signals2 (also in boost). This is implying that you are looking for a behaviour similar to Qt's sigslot mechanism. There are also many alternatives, look at the SO question here.
Explicitly passing this (or perhaps a proxy around this) is pretty much the only (sane, anyway) way to do it, assuming they need to be seperate objects. An object can't and shouldn't need to know number and location of its references. And even if you could get a list of all references to itself, that list could easily contain local variables, items in collections, potentially several instances of A, etc. - how is it supposed to know which one to chose as its parent?
If a B actually "is an" A, you should just make it a subclass.
What other ways are there to have use of the variables in class A
inside of class B?
Since your variables are not static, they are instance variables, so variable1 and variable2 are only meaningful in the context of a specific instance of A - so there needs to be a reference to that instance, not matter how you shape it.
For example, inner classes in Java can use variables of the enclosing outer class directly, but in reality this is just an illusion maintained by the compiler, and in the bytecode, the inner class actually keeps a reference to the outer class instance.
In C++, there is a concept of friend classes: a class A can declare another class B to be its friend, something which gives B access to the private variables of A. Simply write friend class B; inside of A. (As #delnan reminds us, you still need to manually give B a reference to A.)
In Java, if you declare B inside of A, B will become an inner class. Inner classes can only be instantiated from an instance of the outer class, and the instance of the inner class will be tied to the corresponding instance of the outer class, and may access its private variables.
(I agree with #mellamokb, though: This is probably a bad idea, as it creates very tight coupling between the two classes. You might want to rethink your class structure. What exactly are you trying to use this for?)
To reduce coupling between the objects, you shouldn't let B have a reference to A - you should give it a reference to an interface implemented by A. The difference is subtle, but it really makes you think about what actions or data really need to be shared across the interface boundary.

Categories

Resources