http://tutorials.jenkov.com/ood/understanding-dependencies.html#whatis says that (emphasis mine):
Whenever a class A uses another class or interface B, then A depends on B. A cannot carry out it's work without B, and A cannot be
reused without also reusing B. In such a situation the class A is
called the "dependant" and the class or interface B is called the
"dependency". A dependant depends on its dependencies.
According to Google's definition:
a dependent or subordinate thing, especially a country or province
controlled by another.
Since A depends on B, the dependency is A and the dependant is B. This is contrary to the first quote. Or am I missing something?
Terminology is context dependent. In general, the dependency is a synonym of dependence and describes not one entity, but state. According to Cambridge dictionary:
the situation in which you need something or someone all the time, especially in order to continue existing or operating.
So it's more about a relation to something. For example:
A minor child is dependent of his/her parents. The child is in a state
of dependency. The dependency describes the relation between the child and its parents.
The google definition is only one of the available definitions (see for example the Collins dictionary), the one that is especially applicable in the context of geopolitics and real estate. For example:
Before 1776, America was a dependency of the British Empire. The
dependency America was dependent on the Empire.
He bought a farm with several dependencies
The object oriented terminology is not so different from the more general definition: a dependency is a relationship between objects or classes. Here a more formal definition from the UML 2.5 standard:
7.7.1: A Dependency signifies a supplier/client relationship between model
elements where the modification of a supplier may impact the client
model elements.
So, restating what's in the tutorial, we can say that:
If A has to use B, A depends on B. There is a relation of dependency
from A to B. A is said to be the dependent.
For practical reason and language convenience, B is often called the dependency (which is indeed the contrary of everyday's language). But in reality, it is still the relation of A to B that is the dependency.
The thing that is dependent on something is the dependency. I am dependent on H. I need H injected into me. H is a dependency of me.
Related
I thought import and access are types of dependency, but there was a site saying that they're not. It says that the dependency is a little it different with the import/access relationship.
What are the differences? Thanks in advance.
Dependency
A Dependency implies that the semantics of the clients are not complete without the suppliers. The presence of
Dependency relationships in a model does not have any runtime semantic implications. The semantics are all given in
terms of the NamedElements that participate in the relationship, not in terms of their instances.
PackageImport
A PackageImport is a DirectedRelationship between an importing Namespace and a Package, indicating that the
importing Namespace adds the names of the members of the Package to its own Namespace.
PackageMerge
A PackageMerge is a directed relationship between two Packages that indicates that the contents of the target
mergedPackage are combined into the source receivingPackage according to a set of rules defined below. It is very similar
to Generalization in the sense that the source element conceptually adds the characteristics of the target element to its
own characteristics resulting in an element that combines the characteristics of both.
Dependency states that it doesn't have any runtime semantic implications; that must remain true for all subclasses (subclass cannot relax constraints). So if the PackageImport was a subclass of Dependency, then it wouldn't be able to import anything.
To oversimplify: Dependency captures an idea (e.g. this package «use»s this other package, but we don't care how), whilst PackageImport captures an action (e.g. this package «import»s this other package with these precise mechanics).
As a sidenote, they do share a common ancestor in the form of DirectedRelationship
Can composition be bidirectional in a way that both classes are aware of each other?
And if not, what is the default direction of composition?
You should distinguish navigability and aggregation. Arrow and diamond.
Arrow A->B means only that B is reachable from A in some simple way. If A contains a composition of B, it means that
the composite object has responsibility for the existence and storage
of the composed objects (parts).
(citation from OMG Unified Modeling Language TM (OMG UML) - p.109)
So, can composition have bi-directional navigability?
Yes. It is quite normal.
If, for example, you have decided to destroy B in some of its functions, you MUST reach A and destroy it from there. So, composition has bi-directional navigability often enough. Notice, that bi-directional navigability, according to both current and coming UML standards, is shown as line without arrows on both sides. Both-sided arrow is deprecated. THAT is the reason you won't see it often.
Can the composition itself be bi-directional? Can we see black diamonds on both sides of an association?
No, of course this sort of association cannot be mutual, for it is impossible for B to be created in A only and, simultaneously, for A to be created in B only.
What is interesting, the shared aggregation (empty diamond) cannot be mutual, too, but here the limitation is not inherent, it is simply forbidden by UML standard.
Yes, Composition does not add constraints with regards to the navigability of the association.
More info on the difference between Accociation, Composition and Aggregations can be found here: UML Composition vs Aggregation vs Association
From https://www.lucidchart.com/pages/uml/class-diagram:
Bidirectional associations are the default associations between two classes and are represented by a straight line between two classes. Both classes are aware of each other and of their relationship with each other. In the example above, the Car class and RoadTrip class are interrelated. At one end of the line the Car takes on the association of "assignedCar" with the multiplicity value of 0..1 which means that when the instance of RoadTrip exists, it can either have one instance of Car associated with it or no Cars associated with it. In this case, a separate Caravan class with a multiplicity value of 0..* is needed to demonstrate that a RoadTrip could have multiple instances of Cars associated with it. Since one Car instance could have multiple "getRoadTrip" associations-- in other words, one car could go on multiple road trips--the multiplicity value is set to 0..*
In the past I had the same opinion as Gangnus with
So, can composition have bi-directional navigability?
But following some recent discussion I had a more detailed look into the UML specs. And simply, that statement is not true (only partially). Let's look into the UML 2.5 specs. On p. 110 it is stated
Sometimes a Property is used to model circumstances in which one instance is used to group together a set of instances; this is called aggregation. To represent such circumstances, a Property has an aggregation property, of type AggregationKind; the instance representing the whole group is classified by the owner of the Property, and the instances representing the grouped individuals are classified by the type of the Property. AggregationKind is an enumeration with the following literal values:
[omitting shared aggregation]
composite: Indicates that the Property is aggregated compositely, i.e., the composite object has responsibility for the existence and storage of the composed objects (see the definition of parts in 11.2.3).
Composite aggregation is a strong form of aggregation that requires a part object be included in at most one composite object at a time. If a composite object is deleted, all of its part instances that are objects are deleted with it.
Note my emphasis on the object/instance in the above text. So UML just talks of responsibility. If A composes B it will be responsible to delete B when it is destroyed itself. Vice versa B would be responsible for A's destruction. So, if you have references in both directions (i.e. diamonds on both sides) then you will be reponsible to delete the object on the other side. This of course works only if just one of both holds a reference to the other. If both would have a reference, it would not be possible to have a directed responsibility (because it's circular).
I still think that having composite aggregation on both sides is not really a good idea. But according to the specification it is possible.
I'm doing an UML diagrams for a project but I have a doubt...
I use an example to explain:
public class Book{...}
public class Library{
private ArrayList<Book> books;
public void insert(Book b){...}
public Book get(Book b){...}
}
In this case between Book and Library there's an aggregation but also a dependency, right?
Aggregation is a relation in which the "parent" class contains the "child" class, instead the dependency is the case in which a class use another class by parameter or return type.
Now, if a class A contains object of another class B mean that the B's object has been passed in some way at the object of class A, the only way is using a method(or a constructor), so the aggregation involves the dependency?
P.S.: sorry for my poor english
With all due respect to your professor, I disagree. You do have aggregation in your diagram, since Library contains Books (both semantically and syntactically).
A UML dependency relation means that "some UML element or a set of elements requires, needs or depends on other model elements for specification or implementation" (from my favorite UML reference site: uml-diagrams.org). When you put an aggregation link between two elements, it is already stated that one depends on the other, therefore adding a dependency relation between them is redundant.
I am no UML expert, but one thing I've really liked in "UML in a Nutshell" was a sentence saying that UML is useful only when it's intuitive for everybody.
Having said that, I'd suggest not over-complicating your diagrams. Not everything can nor has to be presented in a diagram. In your case the Library has some Books, a case of aggregation/composition (depending on other details not mentioned in your description). You dont have to state a dependency between these two classes, because the aggregation implies it. In my understanding a "dependency" is useful when you want to state an indirect relationship, a runtime dependency for instance.
Many articles/books/.... talk about class or package dependency, few explain what it is. I did find some definitions, but they vary and probably don't cover all cases. E.g.:
"when one class uses another concrete class within its implementation" (so there exists no dependency on an interface?)
"when a class uses another as a variable" (what about inheritance?)
"if changes to the definition of one element may cause changes to the other" (so dependency is a transitive relationship not just on packages, but also on class level?)
"the degree to which each program module relies on each one of the other modules" (but how do you define "relies"?)
Further aspects to consider are method parameters, dependency injection, aspect oriented programming, generics. Any more aspects?
So, can you give a (formal) definition for dependency amongst classes and amongst packages that is fool-proof and covers all these cases and aspects?
If you are asking for dependency in the context of inversion of control or dependency injection, well, you're probably interested in classes that interact with one another directly. That means mostly constructor parameters and properties.
In the context of a UML domain diagram, you're probably interested in "real world" dependency. A dog needs food. That's a dependency. The dog's Bark() method returns a Sound object: that's not something you're interested in, in a UML domain model. The dog doesn't depend on sounds to exist.
You could go philosophical on this also: All classes depend on each other to accomplish a common goal; a (hopefully) great software.
So, all in all, dependency or coupling is not a matter of yes or no. It really depends on the context and on a degree of coupling (weak, strong). I thinks that explains why there are some many divergent definition of dependency.
I wrote a blog post on that topic a while ago: Understanding Code: Static vs Dynamic Dependencies. Basically you need to make a difference between static dependencies, those that are resolved by the compiler at compile-time, and dynamic dependencies, those that are resolved by the runtime (JVM or CLR) at run-time.
static dependencies are typically provoked by calls to static/final methods, read/write to a field, in the definition of the class C the implementation of the interface I by C ... all these associations between code elements that can be found explicitly in the bytecode and source code.
dynamic dependencies are typically provoked by everything that abstracts a method call at compile time, like calls to abstract/virtual methods (polymorphism), variables or parameters typed with an interface (the implementation class is abstracted at compile-time), but also delegates (.NET) or pointers to function (C++).
Most of the time, when you'll read about dependencies in the literature, they are talking about static dependencies.
A static dependencies is direct (meaning not transitive). A tool like NDepend that I mention in the blog post, can also infer indirect (or call it transitive) static dependencies from the set of direct static dependencies.
The idea I defend in the blog post is that when it comes to understand and maintain a program, one needs to focus mostly on the static dependencies, the ones found in the source code.. Indeed, abstractions facilities are used to, well ... abstract, implementation for callers. This makes source code much more easy to develop and maintain. There are however situations, typically at debugging time, where one needs to know what's really behind an abstraction at run-time.
This post is about static dependency - for dynamic dependency and the difference, see
Patrick Smacchia's answer.
In an easy to understand way: an entity (class or package) A depends on an entity B when A cannot be used standalone without B.
Inheritance, aggregation, composition, all of them introduces dependency between related entities.
so there exists no dependency on an interface?
there is, but interface only serves as the glue.
what about inheritance?
see above.
so dependency is a transitive relationship not just on packages, but also on class level?
yep.
but how do you define "relies"?
see above "easy to understand" definition. also related to the 3rd definition you posted.
Update:
So if you have interface A in Package P1, and class C in Package P2 uses A as
method parameter, or
local variable woven into C via AOP, or
class C implements A, or
class C<E extends A>,
then C depends on A and P2 depends on P1.
But if interface A is implemented by class B and class C programs against the interface A and only uses B via dependency injection, then C still (statically!) only depends on A, not on B, because the point of dependency injection is that it doesn't make glued components dependent.
This question already has answers here:
What is the difference between association, aggregation and composition?
(21 answers)
Closed 9 years ago.
What is the difference between aggregation, composition and dependency?
Aggregation implies a relationship where the child can exist independently of the parent. Example: Class (parent) and Student (child). Delete the Class and the Students still exist.
Composition implies a relationship where the child cannot exist independent of the parent. Example: House (parent) and Room (child). Rooms don't exist separate to a House.
The above two are forms of containment (hence the parent-child relationships).
Dependency is a weaker form of relationship and in code terms indicates that a class uses another by parameter or return type.
Dependency is a form of association.
Aggregation and composition are almost completely identical except that composition is used when the life of the child is completely controlled by the parent.
Aggregation
Car -> Tires
The Tires can be taken off of the Car object and installed on a different one. Also, if the car gets totaled, the tires do not necessarily have to be destroyed.
Composition
Body -> Blood Cell
When the Body object is destroyed the BloodCells get destroyed with it.
Dependency
A relationship between two objects where changing one may affect the other.
Aggregation - separable part to whole. The part has a identity of its own, separate from what it is part of. You could pick that part and move it to another object. (real world examples: wheel -> car, bloodcell -> body)
Composition - non-separable part of the whole. You cannot move the part to another object. more like a property. (real world examples: curve -> road, personality -> person, max_speed -> car, property of object -> object )
Note that a relation that is an aggregate in one design can be a composition in another. Its all about how the relation is to be used in that specific design.
dependency - sensitive to change. (amount of rain -> weather, headposition -> bodyposition)
Note: "Bloodcell" -> Blood" could be "Composition" as Blood Cells can not exist without the entity called Blood. "Blood" -> Body" could be "Aggregation" as Blood can exist without the entity called Body.
An object associated with a composition relationship will not exist outside the containing object. Examples are an Appointment and the owner (a Person) or a Calendar; a TestResult and a Patient.
On the other hand, an object that is aggregated by a containing object can exist outside that containing object. Examples are a Door and a House; an Employee and a Department.
A dependency relates to collaboration or delegation, where an object requests services from another object and is therefor dependent on that object. As the client of the service, you want the service interface to remain constant, even if future services are offered.
Aggregation and composition are terms that most people in the OO world have acquired via UML. And UML does a very poor job at defining these terms, as has been demonstrated by, for example, Henderson-Sellers and Barbier ("What is This Thing Called Aggregation?", "Formalization of the Whole-Part Relationship in the Unified Modeling Language"). I don't think that a coherent definition of aggregation and composition can be given if you are interested in being UML-compliant. I suggest you look at the cited works.
Regarding dependency, that's a highly abstract relationship between types (not objects) that can mean almost anything.
One object may contain another as a part of its attribute.
document contains sentences which contain words.
Computer system has a hard disk, ram, processor etc.
So containment need not be physical. e.g., computer system has a warranty.
Containment :- Here to access inner object we have to use outer object. We can reuse the contained object.
Aggregation :- Here we can access inner object again and again without using outer object.