Sparx Systems Forum

Enterprise Architect => Uml Process => Topic started by: jeshaw2 on September 10, 2005, 09:19:17 pm

Title: Modeling Dependency Injection
Post by: jeshaw2 on September 10, 2005, 09:19:17 pm
Dependency Injection is becoming popular.  How are UML modelers diagramming composite classes having a dependency that is injected lets say with a setter method call?

For example, I tried reverse engineering this code:
Code: [Select]

// In Manager.java

public class Manager {

   public static void main() {

       Wheel aWheel = new Wheel();

       Car myCar = new Car(aWheel);  // Note the injection of a Wheel during construction of myCar
   }
}

// In Car.java

public class Car {

   Wheel myWheel;

   public Car(Wheel aWheel) {myWheel = aWheel;}

   private void rotate () {};
}

// In Wheel.java

public class Wheel {

   private int diameter;
   
   public void setDiameter (int dia) {diameter = dia;}
}

What I got was
(http://www.clanshaw.dyndns.org/images/Insertion.JPG)

I don't know why the Manager's associations were not modeled...

Anyway, this is a simple example of what I mean by dependency injection.  Car is a composite structure having an internal structure consisting of aWheel.  I don't get that sense from the diagram.  But I don't know how to diagram that better.  Yes, I can draw a Composit Structure diagram, but how do I show the dynamics of the dependency injection?  Is an Activity diagram the only way to show the dynamics of the injection?

Title: Re: Modeling Dependency Injection
Post by: thomaskilian on September 12, 2005, 12:16:23 am
I'm not really a Java expert, but obviously there is no dependency from Manager to somewhere else. It only has a single method. ???
Title: Re: Modeling Dependency Injection
Post by: Paolo F Cantoni on September 12, 2005, 12:53:37 am
Folks,

We have to be very careful with our language here...

There ARE Dependencies between Manager and the other classes, there are NO (binary) Associations...

That's why the process is called dependency injection!

The reason why the dependencies Jim was expecting aren't modelled is that EA doesn't reverse engineer dependencies within the body of an operation.  That doesn't mean, as we have seen, that they aren't there; it's just that EA doesn't see them.

Another reason why round-trip-engineering from model to code only and back CAN'T work.  Technically, there is insufficient metadata to allow EA to make the right decision, even if it was inclined to.

HTH,
Paolo
Title: Re: Modeling Dependency Injection
Post by: jeshaw2 on September 12, 2005, 07:29:38 am
For those not familiar with Java, Consider the following code:

private Wheel myWheel = new(Wheel);
private Car myCar = new Car(myWheel);

The first line declares a reference variable myWheel to be of type Wheel.  It then initalizes that variable with the expression 'new(Wheel)' by calling the Wheel constructor.  This won't work if the Wheel class is not available.  I think this to be a dependency.

The second line of code does a similar thing for myCar, however the Car constructor is passed the reference to myWheel; this injects a Wheel depenceny into myCar (ref: above code) and adds a second dependency (Car) to Manager.

Paolo;
OK, let's start with these definitions from the UML Infrastructure spec.:
Quote
association
A relationship that may occur between instances of classifiers.
link
A semantic connection among a tuple of objects. An instance of an association. See: association.
dependency
A relationship between two modeling elements, in which a change to one modeling element (the independent
element) will affect the other modeling element (the dependent element).
message
A specification of the conveyance of information from one instance to another, with the expectation that activity will ensue. A message may specify the raising of a signal or the call of an operation.
relationship
An abstract concept that specifies some kind of connection between elements. Examples of relationships include associations and generalizations.


Now help me out here... Are you saying that a message from Manager to Car establishes a relationship between them without that relationship being an association?

PS:  I'm not really conserned about EA's round-trip issues,  I just tried that to see if that would shed any light on this issue of UML diagramming techniques for dependency injection.
Title: Re: Modeling Dependency Injection
Post by: Paolo F Cantoni on September 12, 2005, 11:51:38 am
[
Quote
[size=13][SNIP][/size]
Now help me out here... Are you saying that a message from Manager to Car establishes a relationship between them without that relationship being an association?
To paraphrase Dr McCoy from from Star Trek, "Yes Jim, it's an Association, but not as we know it!" ;D

UML states explicitly that a named navigable association end IS an attribute.  Therefore, a (binary)  Association is about static structure.  Thus, in your initial example, Car has an explicit attribute member, MyWheel which establishes the Association shown in the diagram, for the reasons above.

So what ARE the relationships when Manager uses other classes to do it's job?  Well, what is an Injector?  "I direct a second party to be aware of (associated with) a third party..." How does that sound?

If you like that, then you have a ternary - not binary relationship between three Classifiers.  I'd model it as such...
I'd stereotype the Association "lozenge" as "setter injection", stereotype the AssociationEnd between the lozenge and Manager as "injector", the AssociationEnd between the lozenge and Wheel as "injection" and the AssociationEnd between the lozenge and Car as "injectee".
You can thus read the Association narratively as: "Manager is the injector that injects Wheel into Car".  

From a "compilable model" point of view, it would be a constraint that when you create a ternary Association with such stereotyping, there must also exist a binary Association (attributive) from the injectee to injection.

I have a similar problem when I'm creating code artifacts for source components using my interface:  I have to follow a ternary Association from the component to the Artifact and Class ("For this Component I require the following Class to be in that Artifact.")

BTW: Yesterday (now) I emitted my first operation body, having got around a problem with CodeDOM not understanding the difference between a string and an symbolic literal.. :-)

HTH,
Paolo

BTW, in the absence of the ternary Association, you can do it with a LOT of cross-dependencies...  That's why I made the first statement in the original post...
Title: Re: Modeling Dependency Injection
Post by: Paolo F Cantoni on September 12, 2005, 01:11:34 pm
Quote
[size=13][SNIP][/size]
From a "compilable model" point of view, it would be a constraint that when you create a ternary Association with such stereotyping, there must also exist a binary Association (attributive) from the injectee to injection.
[size=13][SNIP][/size]
A further simplification is possible, but Jim, if you'll humour me, I'll leave it as an exercise for the reader...  ;D

You'll have gathered by now that Dependency Injection may not be the best term for what's going on here...  Attribute Injection may be a better term...

Paolo
Title: Re: Modeling Dependency Injection
Post by: jeshaw2 on September 12, 2005, 07:33:40 pm
Paolo;
Your approach is interesting; I may comment on it later.

I posted this same question on the Spring Forum and got a reply you might find  interesting:
Quote
I encounter similar problem recently. As far as I know, there is no some standard DI modeling techniques. Stil, there is one article on DevX which talks a little about this.

Anyway, I introduce my own solution. If you look at what is really important regarding DI when you look at some class diagram, you will quickly realize that all you really need to know is that some directed association is satisfied (injected) by external entity (lightweight container). In that respect, all you need to do is marking an association with appropriate custom stereotype i.e. <<injected>>. Anybody who knows meaning of this stereotype will immediately realize that this association is injected in object and that object in question doesn't need to implement code for dependency instantiation or lookup.

Hope this help.

Damir Murat


The article referenced is : http://www.devx.com/Java/Article/27583/0/page/1
If you can't see the figures in the article clearly, click on them to open the figure in a larger window.

Both approaches seems to make sense to me.  The mentioned Service Configurator is in a separate package containing the IoC framework (E.g.; Spring).  What do you think of this UML notation?

(http://clanshaw.dyndns.org/images/IoC%20Injection%20Model%2001.jpg)

The Spring package takes the place of the Manager class in my earlier post.

Perhaps this diagram should be done as an object diagram instead of a class diagram?
Title: Re: Modeling Dependency Injection
Post by: Paolo F Cantoni on September 12, 2005, 09:30:51 pm
Quote
Paolo;
Your approach is interesting; I may comment on it later.
[size=13][SNIP][/size]
You can if you like, but you already have... ;D
Elsewhere in the Forums I have asserted that in my view the UML Association "Lozenge: IS the AssociationClass.
Given that is the case (I don't make such assertions lightly...  ;)) Then the AssociationClass you show (ServiceConfigurator) is my lozenge.  
NOTE: the simplification I mentioned as an exercise for the reader was to reduce the number of Associations to only one... (Which you've now done!)

My preference would be to change the stereotype for the (binary) Association to «injected».  Also, I would remove the "Constructor" name of the Association and make it a TargetEnd Constraint {OnConstruction}.  If you intended the injection to ONLY occur on construction, then I'd set the Changeability of the TargetEnd to {addOnly}.

Once you do that, the only thing to add to your solution is to stereotype ServiceConfigurator as «XXXInjector».  This tells you to write the code for ServiceConfigurator as the appropriate Injector Type (a Setter, Constructor or Interface Injector). In your example, this is still a Setter right?

Paolo
Title: Re: Modeling Dependency Injection
Post by: jeshaw2 on September 13, 2005, 04:17:24 am
I'm on my way to work, so quickly...

I'm not familiar with your term lozenge. In my dictionary it is a medicated piece of candy or a rhombus. ???

I didn't mean to give the association a name.  That was a text element I added to the <<injected>> label to indicate 'by Construction'.  I slid them both into an ambiguous location on the diagram to avoid having them overlaying a line and thus being obscured.

Cheers
Title: Re: Modeling Dependency Injection
Post by: Paolo F Cantoni on September 13, 2005, 04:36:45 am
Quote
[size=13][SNIP][/size]
I'm not familiar with your term lozenge. In my dictionary it is a medicated piece of candy or a rhombus. ???
[size=13][SNIP][/size]
OK...  ;)  Formally, the Association "lozenge" is the Chen-style rhombus located beneath the Table Element on the Structure Tool Set.  It is the mechanism to model a generalized n-ary Association.

It is my contention that this "thing" is also the AssociationClass.  It's just a different rendering...

Cheerz,
Paolo
Title: Re: Modeling Dependency Injection
Post by: jeshaw2 on September 13, 2005, 01:26:40 pm
Quote
Elsewhere in the Forums I have asserted that in my view the UML Association "Lozenge: IS the AssociationClass.
 Is there a search keyword that would bring me to those threads?  I'd like to review your comments before I voice my thoughts on the minor differences that I see between them.

Quote
My preference would be to change the stereotype for the (binary) Association to «injected».  Also, I would remove the "Constructor" name of the Association and make it a TargetEnd Constraint {OnConstruction}.  If you intended the injection to ONLY occur on construction, then I'd set the Changeability of the TargetEnd to {addOnly}.
 
Once you do that, the only thing to add to your solution is to stereotype ServiceConfigurator as «XXXInjector».  This tells you to write the code for ServiceConfigurator as the appropriate Injector Type (a Setter, Constructor or Interface Injector). In your example, this is still a Setter right?
I agree with all of this, except in my example the setting was done during a call to the constructor method rather than a call to a setter method.  Just a minor difference.  And since the association is a depencency (albeit injected), I'd like to consider using a dashed line rather than the solid line that appears between car and wheel.

My next step is to replace the Wheel Class with a Wheel Interface and model the ability of the ServiceConfigurator to supply a specific type of wheel as needed by the business environment Du Jour.  

Then, onto modeling dynamic dependency update operations.  That is, Car is programmed to a CarEngine interface.  Now, accelerating from a green light in the city requires use of a FamilyCarEngine, but accelerating from the green light at the Saturday night drag strip requires use of my RaceCarEngine, then a quick switch back to the FamilyCarEngine to drive my wife back home again.  ;D  Both the FamilyCarEngine and the RaceCarEngine implement a CarEngine interface.
Title: Re: Modeling Dependency Injection
Post by: Paolo F Cantoni on September 13, 2005, 04:24:25 pm
Quote
 Is there a search keyword that would bring me to those threads?  I'd like to review your comments before I voice my thoughts on the minor differences that I see between them.[size=13][SNIP][/size]
.
Lozenge works really well...  ;D

Paolo
Title: Re: Modeling Dependency Injection
Post by: SF_lt on September 14, 2005, 04:13:31 am
let's stray a bit:

Paolo, could you post here any class diagram with the N-ary association notation (lozenge :-D) car, wheel and container example would be fine and follow idea

I had difficulties to use this element with it in the past...
Title: Re: Modeling Dependency Injection
Post by: Paolo F Cantoni on September 14, 2005, 05:34:33 am
SF,
Is this what you mean?
(http://sharepoint.knowledgerecovery.com/external/eaug/EA%20Graphics/PaoloFCantoni_Images/AssociationExample.jpg)
I have duplicated Jim's diagram and showed the equivalent using the Association "lozenge".

NOTE: the two associations shown are stereotyped «end» to show they are the AssociationEnds shown in the other rendering.  In a sense, they correspond to the dotted line with the AssociationClass.

The Association and AssociationClass may have additional Associations they participate in and I feel it is important to differentiate those from these ones.

HTH,
Paolo
Title: Re: Modeling Dependency Injection
Post by: SF_lt on September 14, 2005, 12:39:18 pm
Paolo, thanks for the diagram.

Also, I always wondered, why I can't find any example, where "lozenge" is connecting more than 2 classes (and another diagram, which doesn't use "lozenge", but depicts same thing using associations/dependencies).

Title: Re: Modeling Dependency Injection
Post by: jeshaw2 on September 14, 2005, 01:43:33 pm
Paolo;
I've read you views as evidenced by a search on Lozenge and if the following statements are true, I'm in full agreement with you.


If this is not correct, or close to it, I'm confused and need enlightment.
Title: Re: Modeling Dependency Injection
Post by: Paolo F Cantoni on September 14, 2005, 03:53:43 pm
Quote
Paolo, thanks for the diagram.

Also, I always wondered, why I can't find any example, where "lozenge" is connecting more than 2 classes (and another diagram, which doesn't use "lozenge", but depicts same thing using associations/dependencies).
SF,
Here's an example using more than two classes (or Classifiers)
(http://sharepoint.knowledgerecovery.com/external/eaug/EA%20Graphics/PaoloFCantoni_Images/TernaryAssociation.jpg)

I use this ternary in my Code Emitter.  I select the Component to emit, follow the first «end» down to the «manifestation» lozenge.  I then follow the «end» to the «sourceFile».  If I don't already have one, I create a CodeDOM CodeCompileUnit.
I then follow the «end» to the Class and add it (as a CodeTypeDeclaration)  to the CodeCompileUnit I have just identified.
When finished, press Generate and out pops the written code!

HTH,
Paolo

BTW, the notation is my special notation...  I put composition diamonds at the end to make these stand out as «end»s (and also the 0 on the source end of the end...) and also because, to my mind, the Association(Class) acts like a DB intersector table and should have CASCADE DELETE set from all its intersections.
Title: Re: Modeling Dependency Injection
Post by: Paolo F Cantoni on September 14, 2005, 04:03:25 pm
Quote
Paolo;
I've read you views as evidenced by a search on Lozenge and if the following statements are true, I'm in full agreement with you.
  • A simple binary association is just a tuple of ends; ( I think I said that correctly 8) )  This MAY diagrammed with a straight line with perhaps navigation or aggregation symbols at the ends.
  • All other associations are classes with attributes and, optionally, methods.  This may be diagrammed with either a class or lozenge icon and the lines radiating from the icon are the association ends.

If this is not correct, or close to it, I'm confused and need enlightenment.
Just a slight modification.  ALL associations can be shown using the lozenge and the requisite number of «end»s.   The straight line (with optional attached AssociationClass) is a special rendering for binary Associations only...

Finally, there are some associations between the AssociationClass and other classes that aren't part of the Association that is embodied by the lozenge (for example those «attributive» associations belonging to additional attributes in the AssociationClass).  These are shown normally.

Does that clarify things?

HTH,
Paolo
Title: Re: Modeling Dependency Injection
Post by: jeshaw2 on September 14, 2005, 04:24:55 pm
Paolo;
Yep, I'm a happy camper!
Thanks
Title: Re: Modeling Dependency Injection
Post by: SF_lt on September 18, 2005, 11:55:15 pm

Paolo, if don't use lozenge, then there would be 3 associations: logical-sourcefile, sourcefile-xmlemitter, xmlemitter-logical ?
in this way, lozenge would represent each participating classifier's connection with left classifiers (N*(N-1)/2)

Quote
Here's an example using more than two classes (or Classifiers)
(http://sharepoint.knowledgerecovery.com/external/eaug/EA%20Graphics/PaoloFCantoni_Images/TernaryAssociation.jpg)

Title: Re: Modeling Dependency Injection
Post by: Paolo F Cantoni on September 19, 2005, 12:15:15 am
Quote
Paolo, if don't use lozenge, then there would be 3 associations: logical-sourcefile, sourcefile-xmlemitter, xmlemitter-logical ?
in this way, lozenge would represent each participating classifier's connection with left classifiers (N*(N-1)/2)
Yes and No...

Actually, since I posted this diagram, I've realised the actual example is wrong!  The wrongness has to do with Components and Artifacts as Classifiers and NOT instances.  But the incorrectness doesn't affect the explanation below if you consider the 3 boxes as normal classes.

Those of us from the Data Management arena recognize this as fourth and fifth normal forms.

Yes, there are three such associations, but their semantics are not what you may be expecting.  The three associations describe the rules:  Which Components can be associated with which Artifacts and which Artifacts can be associated with which Classes and which Classes can be associated with which Components.

But NONE of them express the ternary tuple: This Class is associated with this Artifact for this Component.  In other words, the lozenge is an intersector.

Naturally, the instance of the ternary tuple has to be in agreement with the rules (the three associations).

HTH,
Paolo
Title: Re: Modeling Dependency Injection
Post by: jeshaw2 on September 29, 2005, 09:05:17 am
Re: Your preference for the term Attribute Injection and more reciently Slot Injection [Ref: Properties, Attributes and Slots thread]. I've just had an Ah Ha! moment.  :)

Up till know I thought that (being 'Up side Down' from me  ;) ), you were taking the name from the injection target (the attribute) instead of from the name of the injected object (a dependency)...

Now I comprehend that you are viewing the process at a higher abstraction level.  Attribute Injection allows anything to be injected, not just a dependency!  Further, Slot injection (a reference to an instantiated object) infers dynamic behavior rather than static structure.

What a concept!  What a lesson to learn in abstract reasoning!   8)

It seems reasonable now to support this static diagram with some type of behavioral diagram to model the injection process.  I'm also thinking that this modeling issue, which is so close to implementation level thinking, might be better diagrammed in an Object Diagram.  What do you think?

Now I'm interested in dealing with the need to model the XML artifact that supports the Declarative Dependency concept within the Spring Framework.  :-/
Title: Re: Modeling Dependency Injection
Post by: Paolo F Cantoni on September 29, 2005, 12:15:54 pm
Don't applaud... Just throw money!

Seriously though, now you see why I'm hooked on this abstraction lark...

The Ah Ha! moment you had, I have frequently...

When you find the right name for something, a lot of things "fall into place".

Quote
[size=13]“Names are the heart of programming.  In the past people believed knowing someone's true name gave them magical power over that person.  If you can think up the true name for something, you give yourself, and the people coming after, power over the code.  Don't laugh!
A name is the result of a long deep thought process about the ecology it lives in.  Only a programmer who understands the system as a whole can create a name that "fits" with the system. If the name is appropriate, everything fits together naturally, relationships are clear, meaning is derivable, and reasoning from common human expectations works as expected.”
[/size] – Todd Hoff ([email protected], http://www.possibility.com/Tmh)


Paolo