Discussions

News: Featured Article: Dynamic Coupling

  1. Featured Article: Dynamic Coupling (37 messages)

    Jeff Schneider discusses the tradeoffs between loosely and tightly coupled components and describes Dynamic Coupling, which involves delaying the assembly interface mechanism decisions to runtime, using an analogy of the 'magic printed circuit board'. He compares 3 differnets kinds of coupling: potential coupling, assembly coupling, and dynamic coupling.

    The Dynamic Coupling Analogy
    "I like to think of the Dynamic Decoupling Device as a 'magic printed circuit board'. Here, the assembler inserts components into the board. But rather than soldering the components together or using plugs to connect them, the assembler will never execute the actual assembly mechanism. Instead, the assembler tells the printed circuit board which components need to be connected to each other. The 'magic printed circuit board' is now responsible for querying the components and determining the best mechanism to connect the piece parts together. We have moved from explicitly stating the connection mechanism to only stating the intent."
    Read Dynamic Coupling

    Threaded Messages (37)

  2. a lot of work[ Go to top ]

    Like the IOC containers it seems like a lot
    of work and complexity for something that
    is simple.
  3. a lot of work[ Go to top ]

    Like the IOC containers it seems like a lotof work and complexity for something thatis simple.
    What kind of work and complexity are you talking about?
  4. IOC[ Go to top ]

    When I read about IOC, I was like "isn't everyone already doing this? Isn't this just called Good Class Design?" It takes something simple, which is to code classes with reduced coupling and makes a _container_ for it?? Why in the heck would you run your regular classes through a container?

    I guess it's every idiot programmer's dream to put all the code in a made-up scripting language or a config file to avoid the apparently evil step of "compiling", but things like this and IOC are just overblown over-architected solutions that aren't needed if you know how to properly write your classes to reduce coupling and increase cohesion.
  5. IOC[ Go to top ]

    It takes something simple, which is to code classes with reduced coupling and makes a _container_ for it?? Why in the heck would you run your regular classes through a container?
    Using IOC/DI container actually encourages Good Class Design. Such a container is very lightweight ( Pico) and simply implements Factory pattern. It does not do anything differently than we would hardcode. IOC framework just simplifies code a bit and makes it slightly more flexible. Again I suggest looking at Pico.
  6. Advantage of a container[ Go to top ]

    Yes, IoC is simple good sense, as is testing for codability. The concept goes back a long, long way. Tapestry has acted like an IoC container for several years, long before I was aware that there was a specific term.

    Why then use a container at all?

    A container enables lazy creation (aka "just in time") of objects. As a system grows ever larger, this becomes an increasingly good thing, especially during the development cycle.

    Why is lazy creation difficult? Two main reasons: dependencies and threading.

    Dependencies cause a problem because service A may need to instantiate service B and service B has a dependency on service C. This means that service A has to know about service B's implementation (not just its interface) including service C. And so forth. Before you know it, you start needing a "central authority" that knows about these dependencies ... and that starts to look like a container.

    Add to this the complexity involved in being properly thread safe. Simple null checks are a problem:

    public void doSomething()
    {
      if (_serviceB == null)
      {
        synchronized (this)
        {
           _serviceB = new ServiceBImpl();
        }

       _serviceB.doSomethingElse();
    }

    That looks thread safe, but is not. The entire method must be synchronized to ensure thread safety (for reasons down in the bowels of the JDK, the language specification, and Hotspot).

    You can have a master factory that's responsible for instantiating all other objects and configure them. All the heavy-duty synchronization can move there. But, again, that's just a very code-heavy container, with a lot of repetition, isn't it?

    Using <plug> HiveMind </plug>, moves the code for thread-safe, just-in-time service creation into the framework, and uses an XML format to identify how to contruct services, including dependencies on other services. That's a lot of code you don't have to write or test (hopefully you can trust the 420+ tests in HiveMind's test suite).

    http://jakarta.apache.org/hivemind/
  7. Advantage of a container[ Go to top ]

    [...] Two main reasons: dependencies and threading.Dependencies cause a problem because service A may need to instantiate service B and service B has a dependency on service C. This means that service A has to know about service B's implementation (not just its interface) including service C. And so forth. Before you know it, you start needing a "central authority" that knows about these dependencies ... and that starts to look like a container.
    Actually, you don't need a container to fix that problem, but good design practice. If one service really needs to _create_ another service do that using a factory. Just a simple core design pattern. Service A does not need to know _anything_ about the implementation of service B.

    Just my 2Cents.

    Regards,
        Dirk
  8. Advantage of a container[ Go to top ]

    [...] Two main reasons: dependencies and threading.Dependencies cause a problem because service A may need to instantiate service B and service B has a dependency on service C. This means that service A has to know about service B's implementation (not just its interface) including service C. And so forth. Before you know it, you start needing a "central authority" that knows about these dependencies ... and that starts to look like a container.
    Actually, you don't need a container to fix that problem, but good design practice. If one service really needs to _create_ another service do that using a factory. Just a simple core design pattern. Service A does not need to know _anything_ about the implementation of service B.Just my 2Cents.Regards, Dirk
    IMO Howrad made a mistake when he wrote that "service A may need to instantiate service B". This is almost never a case and this is not what it is all about.
    In majority of the cases service A only needs to use service B. Don't reallly need to instantiate it. And that is quite big differnce between ""use" and "instantiate". Factories can only help to hide instantiation strategy and this is just a small part of the full picture.
    Note also that Factory DP is often implement as singleton and system with dozen of factories, which are configruable in different ways are rather ugly. That's why it happens quite often that factories are itslef componets whic are provided by container. So I would question if this approch (no container, but factories instead) is really scalable and simpler.

    Michal
  9. Advantage of a container[ Go to top ]

    [...] Factories can only help to hide instantiation strategy and this is just a small part of the full picture.
    Agreed, there's more to dependency injection than instantiating objects. At the end of the day, whether to use a lightweight container or not, is a question of costs.
    [...] Note also that Factory DP is often implement as singleton and system with dozen of factories, which are configruable in different ways are rather ugly. That's why it happens quite often that factories are itslef componets whic are provided by container. So I would question if this approch (no container, but factories instead) is really scalable and simpler.
    Scalable: I don't really see why factories are not scalable. I wouldn't also implement factories using the singleton pattern, unless I need to (for example if the factory must provide some caching mechanisms). Rather, implement it statically.

    Simpler: Ok, that depends upon the concrete situation. But sometimes you _need_ to implmenent factories. For example, if the object creation strategy depends upon parameters that can only be determined at runtime (locales, user information, etc).
  10. Advantage of a container[ Go to top ]

    I have specifically been in situations where I could not use singletons (at least, not as global static variables). For example, Tapestry is a collection of services, but global variables don't work because it is very reasonable to have several different Tapestry applications within the same JVM, or even the same WAR. Therefore, if service A needs to invoke service B, and service B is lazily instantiated, then service A needs to be able to instnatiate service B as needed ... or, carry a reference to an object that can instantiate B on demand (and with thread safety).

    The work I've done on HiveMind is to address those kinds of issues, cleanly and consistently. I've hit these sceanrious many times over the last four years working on Tapestry. HiveMind's Registry acts like a meta-factory, but instead of writing endless boring Java code to connect everything up, it is done dynamically from the XML (or SDL) module descriptors.

    There ends up being a lot of benefits to this. Particularily, you have more and better options for avoiding hard-coding of configuration details such as database URLs and the like.

    Less code == less bugs. Period. I find that a lot of bugs pop up in the most tedious, repetative, boring code ... such as what you would write for a factory.
  11. Advantage of a container[ Go to top ]

    I have specifically been in situations where I could not use singletons (at least, not as global static variables). For example, Tapestry is a collection of services, but global variables don't work because it is very reasonable to have several different Tapestry applications within the same JVM, or even the same WAR. Therefore, if service A needs to invoke service B, and service B is lazily instantiated, then service A needs to be able to instnatiate service B as needed ... or, carry a reference to an object that can instantiate B on demand (and with thread safety).
    I didn't say that singleton should be used. I just made a remark that it is not only a problem of instatiation but also (mainly) the problem of how service A obtains a reference to service B. Variuos implementation of Service B may have different instantiation strategies (singleton, pool, per-lookup and couple more) and those things are hidden from service A. B can be thread safe or not as can be instantiation (per-lookup like instantiation does not need to be synchronized). But resonable container takes care about all those things.


    Michal
  12. IOC[ Go to top ]

    Why in the heck would you run your regular classes through a container?
    Dave,

    I'm with you here. Initially I liked the IoC container idea, especially the non-intrusive ones such as pico. I know the Spring and Pico developers will point out that they don't require interfaces and special methods, however, I suspect that they have their own draw backs in large code bases. Applied at a coarse grained level, lightly managed components make sense. What I've seen happen is that developers take the idea to an extreme and every class becomes managed.

    Each container has it's own way of describing lifecycle and component relationships. What I think Dave is saying is that normally these relationships are expressed explicitly in the code. With the IoC containers it's expressed in XML, via an api, or some other means that aren't as available to the developer that just explicitly setting up the relationships in Java.

    Eventually you have code where the "new" key word is almost never used and the IoC container becomes a memory manager. Reading the code is no longer enough to understand what is happening. My experience is that the container complicates the process of refactoring and unit testing, and creates dependencies that are hidden behind the scenes by the container and it's proprietary method of describing the component relationships. EJB however, didn't cause this problem because it forced developers to think coarse grained, and it only requires container support at the public api layer.

    Taylor
  13. IOC[ Go to top ]

    I disagree to a point, since these are not regular classes, these are supposed to be components, which should have special qualities compared to regular classes:
    - interchangeability - no coupling at all to other components, in order to make them freely interchangeable inside and between containers.
    - configurability - through parameters, outside of source code

    A component can be composed of one or more classes, a defined interface and configuration parameters. What we are gaining with lightweight containers are more freedom and flexibility, compared to EJB for example, which locks you in a restricted API and prevents the use of some OO concepts. But flexibility has a price, and it is up to the developer to find out the what and when of turning classes into components, instead of just hardcoding everything.
    Additionally, containers should provide more than the hooking: other services can be provided to components, and these should increase productivity, since you wont have to code them. Some of these services can even be reconfigured at runtime, making applications even more flexible.
    So there are real benefits to componetization, and the price is more complex configuration instead of just plain coding. But if AOP is really going to stay, then we will just going to see this more and more (scattered code), even unrelated to components and containers.

    Regards,
    Henrique Steckelberg
  14. IOC[ Go to top ]

    I disagree to a point, since these are not regular classes, these are supposed to be components, which should have special qualities compared to regular classes
    True. IoC ,as i believe, is applicable only when we think in terms of components.More often than not,the component name is the name of a class.But,that doesnt mean component is same as "class" in OO.

    The other area where IoC is applicable,is when we think in terms of services.

    surajeet
  15. IOC[ Go to top ]

    Taylor - we're using Spring on a decent-sized project, and we haven't seen any of the problems you've mentioned. I feel the component relationships are expressed very well through constructors that require implementations of the interfaces that they depend on. Class relationships modeled in UML are easily coded in such a manner, and very easy to understand. Unit testing is easy because you don't have to worry about a factory class being configured when testing an object. Refactoring is easy, with the one exception being that a modified classname will need to be adjusted in an XML file (though I believe that some use IDE plugins to handle this). The code is as easy to follow as any code that uses a factory pattern - the main difference being that instead of checking a factory class to find out what interface implementation is being used, you look at an XML file. It's really very easy. I can't agree with your statement that "the dependencies are hidden"; it's really the exact opposite.

    An IoC container is in the simplest sense a factory that you don't have to build and that your classes don't depend on. It's not revolutionary, but I think it's worthwhile. Spring tosses a ton of other features in that make it very compelling. Getting it setup requires very little effort. It's not meant to solve difficult problems, but it does make life easier by handling a lot of application infrastructure. I'm sure the concepts have been around in plenty of other forms for quite awhile, but credit is due to the Spring/Pico/Hivemind/etc. folks for putting together easy-to-use products that allow developers to quickly gain the aforementioned benefits without much effort.

    Rob
  16. IOC[ Go to top ]

    +1 for this.

    I've used Spring on a number of projects now. Not only does it help to steer junior developers into thinking more about coupling issues, but because coupling is recognised as an issue that should be addressed, the object models that result from the design process end up being a lot easier to understand, their dependancies being clearly defined in one way.

    When you add the advantages of being able to test code more easily, my personal response is to begin by assuming the use of Spring (or parts of it) on every project that I'm involved in. I only choose not to when the project so simple that the additional baggage represnts a significant portion of the code, or when the project is highly distributed and transactional, where EJB can sometimes make more sense...

    N
  17. a lot of work[ Go to top ]

    What kind of work and complexity are you talking about?From the document:
    * We use policies to describe capabilities and interfaces.
    * We publish the policies in a consistent manner.
    * We perform protocol negotiation at runtime.
    * We build components with high decoupling potential.
    * We build components that were designed to connect to Dynamic Decoupling Devices.
    * We quit hardcoding our assembly mechanisms.
    * We mandate the use of Dynamic Decoupling in assembly.

    That's quite a lot don't you think? Do a deep dive on
    these and see the added complexity.

    Though i find singletons/factories sufficeint
    for reference resolution as apposed to containers, so
    i guess i am out of step.

    I just see more levels of indirection added, obscuring the code
    even further, for questionable wins.
  18. I just got used to saying[ Go to top ]

    Though i find singletons/factories sufficeint for reference resolution
    that singletons are the same as globals and considered evil. Are you saying that I have to change my mind again ;-)

    ----- Trond
  19. a lot of work[ Go to top ]

    Though i find singletons/factories sufficeint for reference resolution as apposed to containers, soi guess i am out of step. I just see more levels of indirection added, obscuring the code even further, for questionable wins.
    The advantage you gain with IOC is flexibility. If you are building throw-away-applications, you certainly do not need this, but if you need to configure your components so they can be used in multiple different projects, you have to introduce indirection, as otherwise this would not be possible.

    Singletons/Factory Methods tend to make classes final, as static methods can not be overridden. And Abstract Factories require just the wiring that you refuse to use on the pretense of it being to complex (if you want to create them dynamically instead of statically).

    Cheers,
    Lars
  20. a lot of work[ Go to top ]

    The advantage you gain with IOC is flexibility.

    Flexibility to do what? Could you please help me by
    sharing some concrete examples?

    And i assume we are talking about containers. Classes
    have always had ways of resolving references (set, constructor,
    self resolution, etc).

    >Singletons/Factory Methods tend to make classes final, as
    > static methods can not be overridden.

    Certainly the get is static, as that is the access point,
    but what it returns isn't and requires nothing to be overridden.

    >And Abstract Factories require just the wiring that you refuse
    >to use on the pretense of it being to complex
    > (if you want to create them dynamically instead of statically).

    Didn't know i was being pretentious.
    I want to create them so they are obvious and clear in the code.
    I want the code to actually tell me what is going on instead
    of having various meta interpreter layers doing magic things,
    especially when those things are very simple.
  21. A lot of work[ Go to top ]

    Flexibility to do what? Could you please help me by sharing some concrete examples? And i assume we are talking about containers. Classes have always had ways of resolving references (set, constructor,self resolution, etc).
    For me, the main benefit of vanilla IoC containers is clearer code. I don't have any code in many classes that is there to actively resolve dependencies. This is handled by the container. If I have a service class that needs a DAO...

    myDao = DaoFactory.getDao("someName");

    ...has *zero* benefit for me and does not make the code any clearer for me. The Service Locator vs. Dependency Injection debate has been carried out here already, so I am willing to concede that this is a matter of taste. I prefer transparent resolution (by the container). You may prefer explicit resolution in your code.

    The one problem I have with the factory approach is you have to write the code to resolve the look up. When an object requests another object from a Factory, what implementation do you give them? Doesn't this have to be configured and managed somewhere? If it is not configurable, what not make this a static dependency and be done with it? Also, what if this object being created by your factory has other dependencies? And when do you create these objects? Lazily or eagerly? What if these objects are stateful and you cannot just create a singleton, but instead have to create an new object everytime (and resolve its dependencies)? I would rather not worry about this stuff and let a container handle this for me.

    Also, one for thing Spring adds that *is* quite flexible is AOP. Now my container can resolve my dependencies with advised object that I did not even write. They are generated proxies created by the container. I don't have to change *one* line of my client class to get this - that is flexibility!
    Certainly the get is static, as that is the access point,but what it returns isn't and requires nothing to be overridden.
    But you still have to manage what is returned in your code. Why would you want to manage this?
    Didn't know i was being pretentious. I want to create them so they are obvious and clear in the code. I want the code to actually tell me what is going on instead of having various meta interpreter layers doing magic things, especially when those things are very simple.
    If you want to make it sound more confusing than it is, go ahead and call it "various meta interpreter layers doing magic things". It isn't magic. The configuration is quite clear. In fact, we have created XDoclet tags that make the cost for creating Spring managed beans almost zero. A lot of our service layer object look like this:

    /**
     * @spring.bean
     * autowire="byName"
     */
    public class SomeServiceImpl implements SomeSerivce {
        ...
    }

    The container manages everything else, including resolving collaborators and applying advice. One more thing - how is...

    SomeClass someClass = Factory.getSomeClass();

    ... any clearer than...

    private SomeClass someClass;

    public void setSomeClass(SomeClass someClass) {
        this.someClass = someClass;
    }

    ? Again, this may be a matter of taste. I just don't see how you can call IoC container complex and also say that they are doing is simple. What they are doing is suffeciently complex, but they are configured in a quite simple manner, IMO. BTW, what IoC containers have you used?

    Ryan
  22. A lot of work[ Go to top ]

    I just don't see how you can call IoC container complex and also
    > say that they are doing is simple.

    Using a container makes something simple more
    complex because now it has another layer, another
    infrastructure, another thing to learn, another thing
    to check, another thing to write, another thing to
    explain, another thing to update and deploy.
    There's no dichotomy in the statements.

    It's like saying i have a new increment container.
    Use this new increment container and you can
    automatically increment any variable by just
    changing an XML file. In the code you would just
    have xxxx with no idea some configuration file
    is making it get incremented. This analogy has
    holes in it of course, but it touches on the
    flavor of the issue as i see it.

    Of course if you like it, cool, i am just trying
    to understand why, because i don't get it.

    The following statement seems fine to me:

    > myDao = DaoFactory.getDao("someName");

    That seems pretty simple. Easy to use. Clear.
    I can lookup up the documentation in my IDE.
    Easy to write. If i wanted my getDao to use
    a configuration file, database, soap call, etc
    i can easily do so. As a user i just call it.

    One issue is that there are so many containers now.
    This code will work in any environment.

    >But you still have to manage what is returned in your code.
    > Why would you want to manage this?

    Not sure what manage means here. I have to return an object of
    the correct type based on context. There may be many different
    possible parent types that could be instantiated, though a common
    base interface is returned. There could be many complex configurations
    for the different types. Often context is complex
    and requires knowing several different facts to make a judgement.
    I like that judgement code to be immediately visible in
    the code rather than be extracted to elsewhere.

    > BTW, what IoC containers have you used?

    I've tried to use Spring and Pico and then decided
    WTF. I have configuration files, indirection, etc for very little.
    I get the same feeling in struts when i have to put my
    page navigation in XML files.

    In addition i have built my own in large scale distributed embedded systems,
    though they were much more complex because they dealt with
    multi-threaded multi-node system initialization, replication, failover,
    upgrade, etc. Part of my issue is that in an effort to be lite
    containers don't add a lot, imho. More value can be added,
    but then they wouldn't be lite, so people wouldn't use them.
    Odd.
  23. A lot of work[ Go to top ]

    +1 to thoff thoff's comments.

    I think that IoC (the name alone! I think I'll be sick) is just an effort to give a complex-sounding name to a trivial pattern that everybody is using, and many are abusing.
  24. A lot of work[ Go to top ]

    It is always a question of cost/benefit. If you can't see the gain by using a lightweight container, then don't use it. The same can be said by using EJB: if you don't need it, don't use it! Some people have seen the benefits of using a LWFW, but for others, it will be too little, or too much, it always depends on what you are trying to do, size and complexity of the project, team knowledge, etc. But I wouldn't discard them at all, since there are situations where they can be usefull.
    In any new technology, we have the risk of overusing it, thinking that it is the holy grail. Rather, we should always evaluate when and how to apply the weapons we have to fight IT battles: don't use a tank to kill a fly, don't use a needle to kill a dragon. There is no single weapon that wins every battle (despite what Microsoft may say or do ;).

    Regards,
    Henrique Steckelberg
  25. TOE Framework[ Go to top ]

    I agree with Henrique, thoff, Stefan and Lars. In short: with all of you ;-)

    IoC is an old story and always a good design (Interface - Implementation separation, Constructor or Setter dependency, Factory). I just don't agree if someone says that using IoC will solve all your problems and your application will be 100% independent. Somewhere you will have your dependencies (XML, assemble and instantiate the components in your codes, specification, etc.). Just like a real life, we always have those dependencies (if you want to become 100% independent, go to the Moon or Mars ;-) Over there you'll get your independency 100% for sure).

    To help your decision, don't just look at the technical aspects but also on other aspects, just like the TOE (Technology, Organization and Environment) Framework, like what I said in this thread:
    http://www.theserverside.com/discussions/thread.tss?thread_id=26643

    Cheers,
    Lofi.
  26. a lot of work[ Go to top ]

    Could you please help me bysharing some concrete examples? And i assume we are talking about containers.

    Sure: http://www.picocontainer.org/Two+minute+tutorial
    This is very basic, but imagine in our MagicKingdom project (and only there) we need to have a Frog class that'll do something special when kissed. Wiring this is easy, and none of the classes will depend on each other. That's what i meant with flexibility.
    Classes have always had ways of resolving references (set, constructor, self resolution, etc).
    I am unable to disagree with you on this point, but why use these to implement your own proprietary pseudo-container when you can get tested third-party solutions for free that do the same thing better?
    Certainly the get is static, as that is the access point, but what it returns isn't and requires nothing to be overridden.

    Sure, but if you implement a new class to be construct with the factory or want to configure some constructed instances different in some cases, you have to extend the static factory method, may need to introduce some more parameters to its signature, etc. -- meaning you always have to change and test the original code. Moreover, the factory needs to know the classes of all instances it is to construct in advance, so you can not plug classes in dynamically during runtime.
    Didn't know i was being pretentious.

    Sorry, I guess that not what I meant. English is a foreign language to me, but I did not find a better word.
    I want to create them so they are obvious and clear in the code.I want the code to actually tell me what is going on insteadof having various meta interpreter layers doing magic things, especially when those things are very simple.
    Looks like Pico was tailored for your needs, then... :)

    Cheers, Lars
  27. a lot of work[ Go to top ]

    Sure: http://www.picocontainer.org/Two+minute+tutorial
    >This is very basic, but imagine in our MagicKingdom project (and only there) >we need to have a Frog class that'll do something special when kissed. Wiring
    > this is easy, and none of the classes will depend on each other. That's
    >what i meant with flexibility.

    Easier than:

    new Girl(new Boy()).Kiss();

    vs

    Girl girl = (Girl) pico.getComponentInstance(Girl.class);
    girl.kissSomeone();

    The pico solution is clearer? I don't think so.

    In my solution the classes don't depend on each other. One line.
    Very simple. If i need to make it more complex then i can do:

    new Girl(BoyFactory.GetHandsomePrince()).Kiss();
      or
    new Girl(BoyFactory.GetHandsomePrince(BoyFactory.OVER_18)).Kiss();

    Still simple. Still clear. I can add args and it's clear
    what the args are and what they mean by looking at the
    class doc. The factory gives a layer where i can do lots
    of lookups, verifications, notifications, etc, and all that
    is clear in the code.

    Pico on the other hand has introduced a base class, a lifecyle that
    has nothing to do with kissing yet is used to trigger kissing,
    a container that i have to register with, i have to ask the container
    for an instance and then it somehow constructed the object
    using a rules that i can only guess at. Where did the boy
    come from? What args were passed to the boy? What if need
    to other things to the boy before he can be kissed?
    How would i cache boys? Is the same boy used
    every time? When i delete the boy what happens? The life cycle
    is overly simplistic for components in an application. What
    if i want a different lifecycle? Etc, etc.

    Now, in reality you don't want just any boy and any girl. You
    want to "wire" specific boys and girls. That may take a lot of
    context to decide. I like that code immediately visible.

    FYI, i've always liked the pico documentation.


    >I am unable to disagree with you on this point, but why use these
    >to implement your own proprietary pseudo-container when you
    >can get tested third-party solutions for free that
    >do the same thing better?

    Well, i am still not sure that i need help "wiring" my application
    together, so the benifit is unclear to me :-)

    >Sure, but if you implement a new class to be construct with the
    >factory or want to configure some constructed instances different
    >in some cases, you have to extend the static factory method,
    >may need to introduce some more parameters to its
    >signature, etc.

    For a lot of code you don't need factories of any sort. And for those
    that do the code does what is necesary for that object so it
    is very specific and clear what is happening. Trying to get
    rid of this code is a phyrric victory.
  28. a lot of work[ Go to top ]

    First of all, that tutorial is not indicative of how IoC containers are typically used in a real applications. That's like saying the Pet Store is an example of how to write real J2EE applications.

    In the Spring applications I have worked on (we have three currently running in production, a couple more on the way) *none* of my objects are aware of the container. That is kind of the whole point - there is *no* active look up. Going back you your example, if I have...

    new Girl(BoyFactory.GetHandsomePrince(BoyFactory.OVER_18)).Kiss();

    ... I have now statically bound by code to a particular type of Boy. If I am going to do this, why do I need a factory? Why not just do this...

    Boy boy = new HandsomePrince();
    boy.setAge(25);

    ...not really much difference since my factory is not buying me much. My class now knows what implementation it is working with.

    The whole idea behind IoC is to reduce your classes dependencies. This allows you to develop a class that only relies on its collaborators through interfaces. When you introduce factories, your class now depends on the factory *solely* to resolve other dependencies. This makes unit testing harder, because you now have to worry about what object your factor returns. With IoC, you can simply configure the class you are testing with mocks of the required interfaces. When a factory is involved, it gets more complicated.

    Also, when you have a class that depends on factories to resolve dependencies, it can't be used in an envoriment *without* the factory. So any time you want to reuse this class, you have to drag the factory and its configurations along with it. Also, you gave an example of a factory that takes arguments to let it know what type of object to return? How is this configured? In the code? I guess you write on this yourself. What happens when there is another type that can be returned by the factory. Do you go modify the code in the factory? Remind me how this is a better approach.

    In answer to some of your questions...
    Where did the boy come from?
    Who cares? Why does your class care where the boy came from? All your class needs to worry about is that it needs to do something with the boy. The boy's lifecycle is not a concern of your class.
    What args were passed to the boy?
    Again, why do you care? That is not your classes concern, it it?
    What if need to other things to the boy before he can be kissed?
    You can execute whatever initialization you need before your object it obtained.
    How would i cache boys?
    Cache or pool? These have different meanings for me.
    Is the same boy used every time?
    Yes and no. You can do both. You can use the same instance everytime (singleton). Or it can be a new instance everytime. Or it can be pulled from a pool.
    When i delete the boy what happens?
    Not sure what his means. Delete from where, the database? Or did you mean dereference? Again, this depends.

    The Boy/Girl example was not a good example. Typically you will be wiring infrastructure components, not domain objects. For domain object (PurchaseOrder, Employee, etc) you can and will create them using the "new" keyword. Creating object via a constructor is not banned. But there are lots of infrastructure classes that can benefit from being wired together via IoC.

    Hopefully this answered some questions.

    Ryan
  29. a lot of work[ Go to top ]

    First of all, that tutorial is not indicative of how IoC containers are
    > typically used in a real applications.

    A tutorial might want to show good usage :-)

    > *none* of my objects are aware of the container.

    The association has to be setup somewhere doesn't it?
    When creation happens the container needs to get control?

    >new Girl(BoyFactory.GetHandsomePrince(BoyFactory.OVER_18)).Kiss();
    >... I have now statically bound by code to a particular type of Boy.

    Not at all. GetHandsomePrince could return Boy or it could return Kissable.
    Having a HandsomePrince class wouldn't be done, no more than i would
    have a BlueCar class. What it is saying is i want a handsome prince.
    Figure that out using whatever criteria you use.
    In addition, apply the criteria that the prince is over 18. It could
    be done using a SQL query. It could be done using a soap call to the
    handsome prince registry. Doesn't matter.

    > Why not just do this..
    >Boy boy = new HandsomePrince();
    > boy.setAge(25);
    >...not really much difference since my factory is not buying me much.
    > My class now knows what implementation it is working with.

    I would see the handsome prince relation being satisfied another way, not
    via a class. See above. So the factory adds a lot. And how it does it is
    easily visible. I don't really ever see just creating a HandsomePrince, because
    you are usually creating something that has identity. It has attributes
    in a database that need to be sucked up to populate the object. You
    can't just create and hookup transient classes. They have to be a
    particular boy that everyone referencing that boy knows they
    are referencing the same object.

    >What if need to other things to the boy before he can be kissed?
    >You can execute whatever initialization you need before your
    >object it obtained.

    How is this done? It seemed pico was creating the boy and passing
    constructor args.

    > What args were passed to the boy?
    > Again, why do you care? That is not your classes concern, it it?

    They are in my application. I am using them. How can you ask
    why do you care?

    > Typically you will be wiring infrastructure components, not domain objects.

    Well that explains a lot. Thanx. It makes more sense for transient
    objects. Though my preference is to do things consistently and the
    factory way still seems simpler, clearer, and more general.
  30. Best Practice?[ Go to top ]

    Typically you will be wiring infrastructure components, not domain objects.
    This seems important to me, because it suggests an IoC container Best Practice. Could you elaborate on this a little more? Also...

    1. What are infrastructure components?

    2. Are there other IoC container best practices?

    Thanks in advance.

    best,
    assmund
  31. Best Practice?[ Go to top ]

    Well, since the IoC containers being discussed are still quite young, best practices are probably just now being established as people put them to real use. So, these comments are from my experiences...

    By infrastruture code, I mean the objects that provide the plumbing and services for you application. DAO objects. Transaction managers. Database connections. Service layer object (thinks Session Bean without the EJB). Web components (e.g. Struts actions). These objects depend on one another. Spring can wire these objects for you so each one of these object can focus on its task at hand. The powerful add-on provided by Spring is its AOP framework. You can write these infrastructure object that do their job (persist data, apply business rules, handle web requests, etc) and apply new functionality to them via aspects (transactions, security, etc). The IoC + AOP is a great one-two punch.

    When I say domain objects, I am referring to the objects that represent the entities in you application. For example, you may have an Order object that contains Detail objects. These represent real business entities. Then you may have an OrderServices and an OrderDao object that offer services and persistence for the Order objects. The Order and Detail objects are domain objects. So far I have not let the container manage these object (IIRC). They are managed within my application in various places. My persistence tool (typically Hibernate) may instantiate these objects when I pull them from the database. The web components may instatiate these objects when they are created via a HTML form. Basically, I have not found a need to obtain my domain objects from a factory that is managed by Spring (not that this should always be avoided).

    One thing I *have* been thinking about is how to apply advice to domain objects. With Spring's IoC framework, Spring must be aware of the objects in order to provide advice. That would mean that if I wanted to advise my domain objects, I would have to get them from Spring's BeanFactory. This is not always possible (i.e. what if Hibernate is creating my domain object what I query the database?). Something for me to think about...

    Ryan
  32. Correction...[ Go to top ]

    One thing I *have* been thinking about is how to apply advice to domain objects. With Spring's IoC framework, Spring must be aware of the objects in order to provide advice. That would mean that if I wanted to advise my domain objects, I would have to get them from Spring's BeanFactory. This is not always possible (i.e. what if Hibernate is creating my domain object what I query the database?). Something for me to think about...Ryan
    All this is assuming applying aspects declaratively. Using Spring, you *can* apply aspects to objects that are not created via a BeanFactory, you just have to do so programmatically using Spring AOP APIs. Of course, my preferred approach would be to avoid this.

    Ryan
  33. Mixed Metaphors[ Go to top ]

    This article is absolutely horrible. It not only mis-uses certain terms, but the author mixes methaphors and goes around and around without making a strong point or providing ANY evidence that his claim (whatever it is) is worthy. Does anyone know how to write anymore?

    Loose coupling doesn't speak to the "least common denominator". It reduces the dependance of one class on another, making the class in question more re-usable. It has nothing to do with distributed computing or network transparency.

    Then he mis-uses the term to say that a component is "enabled to be loosely coupled". A component is either loosely coupled or not, with respect to another component. And this is known at design time.

    HIs description of "assembly coupling" is somewhat nonsensical, as he mixes up adapters and his component by saying that a component is loosely coupled depending on which adapter was used to connect it to other components (the adapters are components themselves).

    This would all seem more credible if he had bothered to show some code that did whatever it is Dynamic Decoupling is supposed to be and then demonstrated how it was superior to the "naive" implementation.

    It's this kind of fluff article that has no logic or substantiation behind it that makes TSS to look like a total joke. An article like this one would be laughed at my any serious researcher or computer scientist.
  34. Mixed Concepts[ Go to top ]

    The author seems to speak about components, not classes. In this case I think he is using an adaptation of the term "coupling", normally applied to classes. Components should not be confused with classes though, they are different beasts (although similar under some aspects). Maybe that can clarify some of what he is trying to say...

    Regards,
    Henrique Steckelberg
  35. Mixed Concepts[ Go to top ]

    I recommend the following article by Martin Fowler, maybe it can enligten some of what is being discussed here:
    http://www.martinfowler.com/articles/injection.html

    Regards,
    Henrique Steckelberg
  36. Mixed Metaphors[ Go to top ]

    +1
  37. Featured Article: Dynamic Coupling[ Go to top ]

    How is "Dynamic Couplinq" different from Late Binding?

    Carlos
  38. Dave C[ Go to top ]

    If article is not good, the best way is to explain it in a better way why it is not good, instead of attacking the author.