Slashdot Mirror


Dependency Injection with AspectJ and Spring

An anonymous reader writes "IBM DeveloperWorks has an interesting article about the complementary aspects of dependency injection and aspect-oriented programming. Adrian Colyer, Chief scientist of Interface21, examines how to combine these two techniques to 'facilitate advanced dependency injection scenarios.' From the article: 'Dependency injection and aspect-oriented programming (AOP) are two key technologies that help to simplify and purify domain models and application layers in enterprise applications. Dependency injection encapsulates the details of resource and collaborator discovery, and aspects can (among other things) encapsulate the details of middleware service invocations'"

48 comments

  1. Eh, wot? by jo42 · · Score: 1

    Who wrote that? The Marketing Department?

  2. Dependency injection? by radical_dementia · · Score: 0, Troll

    Well you sir are a fastishio, see I can make up words too.

  3. Good News! by maxcray · · Score: 5, Funny

    This is good news! I have long wanted to "encapsulate the details of middleware service invocations".

  4. Question for ScuttleMonkey: by Anonymous Coward · · Score: 0

    Did you understand the summary? Or do you just post anything with a lot of buzzwords in it?

  5. My brain hurts... by advocate_one · · Score: 4, Funny
    honestly, does anyone actually understand what the heck they're going on about here???
    'facilitate advanced dependency injection scenarios.' [...]'Dependency injection encapsulates the details of resource and collaborator discovery, and aspects can (among other things) encapsulate the details of middleware service invocations'
    --
    Donald 'Duck' Dunn: We had a band powerful enough to turn goat piss into gasoline.
    1. Re:My brain hurts... by poopdeville · · Score: 0, Offtopic

      It's straightforward. See, the pirate (who is made of rubber, btw) wants to become the pirate king, and so is sailing around the "Grand Line" (or "equator") kicking the shit out of other pirates and picking up a crew of dedicated sailors.

      --
      After all, I am strangely colored.
    2. Re:My brain hurts... by Artega+VH · · Score: 1

      Yes.

      Although I do agree that whoever wrote the article could have used easier words. You have to already be familiar with Dependency Injection (or IoP) and AoP to actually understand. Which sorta voids the purpose of the article.

      --
      groklaw, wired and slashdot. The holy trinity of work based time wasting.
    3. Re:My brain hurts... by Kj0n · · Score: 5, Informative

      I understand it, but only because I already know this stuff.

      A better article to start with is: Inversion of Control Containers and the Dependency Injection pattern, by Martin Fowler. It's older than the one mentioned in the story, but still relevant.

    4. Re:My brain hurts... by ObsessiveMathsFreak · · Score: 2, Funny

      honestly, does anyone actually understand what the heck they're going on about here???

      More or less. Essentially the author is saying:

      "Buy My Book....Buy My Book...."

      --
      May the Maths Be with you!
    5. Re:My brain hurts... by uradu · · Score: 1

      Rats, for a moment there I thought they came up with a new shot to fight cocaine addiction. No such luck...

    6. Re:My brain hurts... by gedhrel · · Score: 2, Informative

      Dependency injection: software is written by decomposing a problem into functionally distinct components. Those components might be self-contained, which makes things easy. In any case, each component fits a particular purpose. If you view that purpose as a contract, the component fulfuls the contract; what you'd like to do is to be able to interchange the implementation of a particular component simply. All you need to know is that a particualr implementation fulfills the demans of the contract for that component. ("Contract" here means the API, or interface, together with the semantics of that interface.)

      There are patterns that let you select individual components with late binding - ie, at runtime. "Abstract Factory" is a good google term to look for.

      Anyway, some components are not self-contained. They require other components to fulfil their contract. Again, they may not care about the _implementation_ of those components; only that those components exist. Those secondary components might be used solely by the component in question (a "resource") or might collaborate as a peer (a "collaborator"). In either case, the question you face is: this block of code requires a "Foo": how do I get an implementation of "Foo" into it?

      That summarises the problem that Dependency Injection attempts to solve. The clue is in the name: the creation of required components is handled by an external framework (the components themselves are not responsible for the creation of their resources or collaborators): hence the phrase, "Inversion of Control" to describe this approach.

      The article discusses the use of AOP to manage dependency injection: it's an IoC framework expressed using AOP constructs.

    7. Re:My brain hurts... by gedhrel · · Score: 1

      Having said that, I'm still not sold on AOP. My concern, I realise, is that AOP is prone to the same problem that makes people denigrate operator overloading (a language feature that I find particularly appealing): it's easy to write absolutely unmaintainable code using AOP. My gut instinct is that AOP is more prone to this than (say) operator overloading, since aspects are rather more widely distributed through source than the latter.

      I guess the conclusion (which is the one I also draw about operator overloading) is that AOP is a powerful technique and is more harmful than good in the hands of less than expert practitioners. That makes me nervous about it: I've heard amazing claims about the maintainability of codebases that use AOP, but I'm not sold. A little, in the right places? Perhaps. The approach in this article is interesting, but I'm not convinced it's really the right place for it.

    8. Re:My brain hurts... by AuMatar · · Score: 1

      AOP- because setjmp and longjmp were so much fun.

      --
      I still have more fans than freaks. WTF is wrong with you people?
    9. Re:My brain hurts... by Marxist+Hacker+42 · · Score: 1

      And this is different from inheritance wrapping into a translation class exactly how?

      --
      SJW: a person who perceives an injustice, and while correcting it, commits a greater injustice.
    10. Re:My brain hurts... by heinousjay · · Score: 1

      Implementation.

      I know this answer provides no value. I was guessing from the tone of your question that you don't really care to have it answered anyway.

      --
      Slashdot - where whining about luck is the new way to make the world you want.
    11. Re:My brain hurts... by Marxist+Hacker+42 · · Score: 1

      Actually, I would have welcomed an answer with value. But since I don't know Java, I guess what you're telling me is that it's a slightly different syntax.

      --
      SJW: a person who perceives an injustice, and while correcting it, commits a greater injustice.
    12. Re:My brain hurts... by gedhrel · · Score: 1

      Er. Ok. The way you implement concrete components (that reify an interface) may indeed utilise inheritance; depends on the language. Not sure what you mean by "translation class" - a wrapper?

      "Dependency Injection" doesn't really care about that. What it's concerned with is how particular components locate the other components they have to interact with.

      Possibilities: hard-coded instantiation -

      Foo foo = new Foo(); // not DI

      the same kind of thing, but using reflection

      Foo foo = (Foo) Class.forName(fooClass).newInstance(); // not really DI either

      a factory object:

      Foo foo = fooFactory.makeFoo(); // might be ok. But how do we get hold of fooFactory?

      or, an external framework that has instantiated this object gives it the collaborators it is after:

      public void setFoo(Foo foo) { this.foo = foo; }

      That's a DI approach: the burden of creating the dependency is on the instantiating framework. Details of the precise langauge mechanism used to inject these dependencies (using a constructor, using setter methods, etc) vary between frameworks. The article gives a approach expressed using AOP constructs.

    13. Re:My brain hurts... by Krach42 · · Score: 1

      OOO! I get it know...

      So, it's exactly like what I've been doing with my object oriented approach to C coding, that doesn't make sense in OO languages because the syntax makes you lazily pick the non-DI way...

      --

      I am unamerican, and proud of it!
    14. Re:My brain hurts... by Marxist+Hacker+42 · · Score: 1

      Ok, so I was completely wrong. It's more like what microsoft developers call intrinsic binding, rather than merely wraping a class in another class to translate between two disparate systems. It also contains some aspects of Microsoft's late binding in that it doesn't matter where a class is at compile time (or even if you have a copy of the class or it's wrapper installed on your machine at compile time).

      --
      SJW: a person who perceives an injustice, and while correcting it, commits a greater injustice.
    15. Re:My brain hurts... by gedhrel · · Score: 1

      Late binding is exactly it. Lots of ways to do it: dependency injection is one approach. Shoving implementations into a tree/namespace of COM objects at well-known locations is another way. The important thing is that the burden of selecting the implementation and instantiating it is not on the class that uses it, but on the framework that provides it.

  6. More AOP articles wanted by Ghost+Hedgehog · · Score: 1

    Finally, with more articles like this I can say that reading Slashdot is actually good for my thesis on AOP.

  7. Spring by ackdesha · · Score: 2, Insightful
    If you think you even might be involved in a new j2ee proj., a good book that explains much of this complexity (or maybe buzz) is Rod Johnson's (of Spring notoriety) J2EE without EJB. I think their movement suffers to some degree from over abstraction, but it does beat EJB and is my choice for j2ee development.

    I'd rather use RoR or any other dynamic language for web dev in general. However, there are still many business requirements that can come up (OLAP for one - Mondrian) that keep me coming back to j2ee for now.

    The Spring framework reduces IoC and AOP to configuration details (XML - blech) so you don't have to worry to much about the implementation. Very powerful I'm sure in the hands of a seasoned Spring user.

  8. one good project from this? by yagu · · Score: 2, Insightful

    Aside from more jargonism, can anyone cite one major application, one major project for which this was used?

    I'm signing up for my 10-year training plan to learn the terminology, jargon, etc.

    Then I'll consider if I even want to learn to apply it. Sheesh, this is embarrassing

    1. Re:one good project from this? by angel'o'sphere · · Score: 1


      Aside from more jargonism, can anyone cite one major application, one major project for which this was used?

      Every major development uses either J2EE (JBoss, WebSpehre or what ever)
      OR: Spring + Hybernate + AspectJ

      Why don't you google for it ;D

      And yes, if you code in java you should get familiar with at least one of those.

      angel'o'spehre

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    2. Re:one good project from this? by heinousjay · · Score: 1

      Sure, I'm building one right now. You can't get to it, though, and I'm not really allowed to tell you much about it.

      Most of these applications aren't high-profile public projects. Typically, you're talking about internal business systems.

      Overall, it's important to remember: Your belief in the value of a given technique has no effect on the actual value therein.

      --
      Slashdot - where whining about luck is the new way to make the world you want.
    3. Re:one good project from this? by maraist · · Score: 1

      Aack.. You got me at both ends..

      j2ee != jboss/websphere..
      EJB == jboss/websphere.
      j2ee incluedes servlets (tomcat), mail, encryption and transactions..

      Then on the other extreme, you groups AOP w/ spring+hibernate.. evil evil man.

      I find myself in the situation that when I move on to bigger and more profitable projects, my legacy code gets taken over by outsourced Indian groups, and the shere number of buzz words involved is enough to make their heads explode I should think.

      --
      -Michael
  9. film star? by willCode4Beer.com · · Score: 0, Troll

    "Rod Johnson"? Sounds like the name of a new adult film star.

    --
    ----- If communism is a system where the government owns business, what do you call a system where business owns govern
  10. Summarizing the summary by metamatic · · Score: 1

    To summarize Fowler's summary:

    It's a complicated way of getting around some problems caused by Java; problems which don't occur in dynamic languages such as Ruby.

    --
    GCHQ Quantum Insert installed. If only our tongues were made of glass, how much more careful we would be when we speak
    1. Re:Summarizing the summary by angel'o'sphere · · Score: 1


      It's a complicated way of getting around some problems caused by Java; problems which don't occur in dynamic languages such as Ruby.


      Please explain ... probably Ruby might have advantages there over Java, but surely not because it is dynamic typed. What do you mean by "those probelms"? Please give an example!

      angel'o'sphere

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    2. Re:Summarizing the summary by metamatic · · Score: 2, Informative

      Take the example given. He defines an API for communications between the application and something that looks up movies for a given director, which he calls the finder.

      In Java, he needs to instantiate a particular concrete class to provide the finder service. Because of Java's insistence on compile-time type safety, this presents a problem. He wants to be able to plug in a ColonDelimitedMovieFinder class as his finder initially, but still allow someone else to plug in a SQLMovieFinder or whatever without modifying the MovieLister class. So, he has to build a special bit of code to inject a chosen implementation--his PicoContainer with its registerComponentImplementation thing.

      In Ruby, you can instantiate any object you like as the finder, because all that matters is that it understands the API messages when it gets them at run time. All you need to do is have a setter method in the original MovieLister object that accepts an object to use as the finder; and you can define that in 1 line of code. Then the MovieLister just uses the object it was passed as the finder. The user of the MovieLister library can then plug in any implementation he likes; he can even change implementation while the application is running. No injectors, no containers, no fancy component libraries needed.

      In fact, here is a complete implementation in Ruby, with an example of calling it. (Indentation stripped courtesy of Slashdot, so run it through vim or something.) Note how I simply use a CSV parser object as my Finder, because MovieLister just needs the finder to have the standard Enumerable interface for returning each movie and director in the list.

      require 'csv'

      class MovieLister
      attr_writer :finder

      def movies_directed_by(director)
      if not @finder
      raise "Finder not set before calling movies_directed_by"
      else
      result = @finder.collect {|dirname,movname| movname if dirname == director }
      result.delete(nil)
      return result
      end
      end
      end

      finder = CSV::Reader.parse(File.open('movies.csv'))
      lister = MovieLister.new
      lister.finder = finder
      puts lister.movies_directed_by('Stanley Kubrick')

      Again, no special libraries or frameworks were required. Only CSV, and that's in the standard library.

      --
      GCHQ Quantum Insert installed. If only our tongues were made of glass, how much more careful we would be when we speak
    3. Re:Summarizing the summary by Anonymous Coward · · Score: 0

      I'll restate your summary, and your example which follows:

      I'm going to restate the problem space to fit my solution, even though it misses the point in many essential ways, because I'm a Ruby Zealot, seeking affirmation and validation by making other people agree with me.

    4. Re:Summarizing the summary by maraist · · Score: 3, Interesting

      I'm sorry, but you are incorrect.

      Dependency injection has NOTHING to do w/ weak or strict type-safety (and, in fact, a concrete class is not required at all.. reflective interface handlers often can facilitate service needs). And if you use dyna-beans, then neither the producer or consumer ever even need an interface.

      Your example shows the exact flaw in coding that Inversion of Control (through setter/constructor injection) solves.

      Namely that you explicitly had to configure your dependencies. Yes, due to weak-types in such languages you could take almost any arbitrary code and plug it in to fullfill the server.. The fact still remains your code explicitly configured it.

      The idea of Inversion of Control is that the thing that needs a service should NEVER configure that service. It's the law of demiter. If I want to use some thing, I shouldn't need to know that it in turn uses something else. If I have to configure both the thing that I want to use AND the thing that it wants to use, then eventually all my code is convoluted (doing and configuring crap that has nothing to do with what I'm actually trying to do).

      If you simply take a step back and have something that uses the service configure the service, you'd still have to point some code to the thing that configured the service, so you're just moving the problem around (which is what your example does).

      Inversion of control allows you to define the entire application modularly where each module only cares about capabilities of external modules (not their configurations nor their nested dependencies). In your example, the type-weak language merely requires the positional arguments to be compatible (which, I agree is a very powerful thing.. Perl's "grep", "map" and "sort" commands are incredible). In java, it would require an explicit class (interface or conctrete).

      When you build your application this way, and you generalize your inter-component communication as genericly as possible (yes perl,ruby,python can much more easily genralize a service), then you can plug pieces together that were never originally meant to work together.

      Another very important aspect of IoC is that you can easily test each piece separately, as instead of an application-confired container, you have a testing-configured container which performs appropriate configurations suitable for testing and unit-isolation.

      With setter and constructor injection and through the use of interfaces, you facilitate mocking of 3'rd party services such that you completely skip all the complexity of side components and focuses very specificly on what a single component is doing.. You can test 'what would this module do if it's dependency returned something unexpected'.

      If you have a perl module that internally uses some other class, how could you easily test interaction with the other class (say a IO::File). Typically you create test files. But what about when it's a database or a web site.. Your unit tests get more and more complicated. Especially if what the module is doing has is really independent of the fact that it's using a URL or database.

      If instead the module was fully configured externally (no default configuration w/ zero-arg constructors or default package global variables), then you would be assured that you have full control over the environment of the module in question.

      Thanks to these types of interactions, the power of object-orientation can be exploited while at the same time using singletons (essentially context-specific global variables; an otherwise anti-pattern). This has a trade-off of faster execution time at the cost of a higher memory usage and slower startup time. The fact that IoC usually has a non-neglegable setup time often means that we lean towards singletons (which has implications on code design).

      Finally, the code you showed is fine for alternating configurations.. And for small tasks, the overhead of IoC is simply not justified. IoC really comes into it's own in very large p

      --
      -Michael
    5. Re:Summarizing the summary by angel'o'sphere · · Score: 1

      Sorry,

      but thats not right.

      finder = CSV::Reader.parse(File.open('movies.csv')) this line is a dependency. You obviously depend on CSV:: and you have hardcoded the dependency here.

      IoC or Dependency Injection is about how to avoid hardcoding dependencies between components.

      In IoC frameworks you usually use an external description file, e.g. an XML file (deployment descriptor) or an AOP code snipped.

      A generator or a runtime component would read that fiel and insert your line: finder = CSV::Reader.parse(File.open('movies.csv')) at teh appropriated place. Point is: your exampel is not reuseable. Except if you cut/paste it and rewrite that certain line ....

      IoC is about how to make your code more reuseable.

      angel'o'sphere

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    6. Re:Summarizing the summary by metamatic · · Score: 1

      It would be trivial to make the choice of CSV::Reader depend on an external config file if you want:

      chosenclass = File.open("config.txt").gets.chop
      finder = chosenclass.parse("movies.csv")

      The example *is* reusable. Those lines you pick out aren't part of the class library, they're an example of how you can call it with whatever class you like (even one chosen from a config file), without needing any kind of complicated scaffolding like in Java. I just put them in to demonstrate that the code actually works.

      The point is with a dynamic language you avoid all the gyrations required to get around the rigid type system.

      --
      GCHQ Quantum Insert installed. If only our tongues were made of glass, how much more careful we would be when we speak
    7. Re:Summarizing the summary by metamatic · · Score: 1
      The idea of Inversion of Control is that the thing that needs a service should NEVER configure that service.

      In that case, the article cited was incredibly badly written. What's more, I fail to see how the example given in Java achieves the supposed goal. How does that Spring XML file get written, if not by whoever is using the service code?

      --
      GCHQ Quantum Insert installed. If only our tongues were made of glass, how much more careful we would be when we speak
    8. Re:Summarizing the summary by maraist · · Score: 1

      Other posters have explained this better than I, and the links will as well I'm sure.

      But the idea is that in spring/pico/nanno/etc the configuration description is a deployment issue, not an application issue.. It's like editing /etc/X11/xorg.conf. By merely twiddling fields in a sample xml-configuration, you can dramatically alter what the entire product does. Mixing and matching sorters, data-repositories, inter-process communication tools, etc. It also allows a trivially easy way of mixing matching default values.. Is the default a simple string or a JNDI-looked up value, or the result of calling some factory object. You can easily switch between these forms of configuration by adjusting the spring.xml file.

      And as for generating a stock/base/initial spring.xml file, there are xdoclet tools that will build them.

      --
      -Michael
    9. Re:Summarizing the summary by gedhrel · · Score: 1

      Unlike some of the other comments here, I think you've basically got it. Examples in Java can be as simple as this, too: the "icing" from DI frameworks is that they generally use introspection and reflection to manage object instantiation and to "jsut work" against any set of classes that you'd like to instantiate and supply dependencies to. You can knock that up in Ruby pretty simply; it's as straightforward in Java, too, but the expression of the reflection code is typically more verbose.

    10. Re:Summarizing the summary by angel'o'sphere · · Score: 1

      Your example would look the same in Java (or any other stron typed language).

      I simply don't understand which point you want to make ;-)
      And as the core question was: Why is IoC easyer in Python than in Java? You failed IMHO to answer that question.

      In Java your code would only look like this:

      SomeType chosenclass = File.open("config.txt").gets.chop; // probably this is a call? Then add ()
      SomeOtherType finder = chosenclass.parse("movies.csv");

      Voila! Exactly the same simplicity like in Python, except that we added static type information. And this has nothing to do with IoC. SomeType would likely be String and SomeOtherType likely an interface called Finder.

      IMHO the rigid type system makes working with IoC not harder. In fact it makes it more precise ... as I can see what a component requires.

      angel'o'sphere

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    11. Re:Summarizing the summary by metamatic · · Score: 1

      OK, so if you can read a class name from a config file and call that class, why is all that other stuff in the article necessary? I guess I'm still not getting the point of it all.

      --
      GCHQ Quantum Insert installed. If only our tongues were made of glass, how much more careful we would be when we speak
    12. Re:Summarizing the summary by angel'o'sphere · · Score: 1

      The article is about this:

      you have several classes that work together. Usually one or mroe of those classes would instanciate each otehr to get a net of objects. So at least one of them has the complete construction process of all objects involved in on of their constructors.

      If a new class is ment to reuse this network, it has again a construction statment for the root class of the used network.

      The more classes you have the ore are constructions, calls to new, clutterd as hardcoded dependencies all over your source code.

      The IoC pattern attempts to seperate classes and their responsibility from constructing objects from other classes by moving initialisation code of groups of classes outside of those classes into a container or "factory" which is usually configured via external files.

      angel'o'sphere

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    13. Re:Summarizing the summary by magicmonster · · Score: 1

      "the thing" is meant to the class, not a person. The class shouldn't know about which implementations of its components it should be using. Using inversion of control moves that responsibility away from your class.

    14. Re:Summarizing the summary by j3110 · · Score: 1

      Yes, but ruby allows all kinds of stuff like this very simply by "reopening" the object and adding in your code as desired.

      Spring allows Java to inject code.

      Ruby has inate support for injecting code.

      class Hash
        def to_s
          return 'hello';
        end
      end

      You can override any method from any point in the code.  This can be your best friend or worst enemy.  It will, however, make dependency injection trivial.

      --
      Karma Clown
  11. Explanation... by boicy · · Score: 1
    IANAAOP

    OK, I think that it's fair to say that AOP is still very much at the cutting edge of developement in the java community.

    Essentially the idea with AOP is that you increase the modularity and decrease the coupling of components in your application. An example of this would be Logging.

    Now most (if not all) apps need to have logging code of one sort or another. This means that the code necessary to log to whichever system (commons-logging, log4j etc in the java world) you use tends to touch all of the classes/objects in your application.

    Consider a situation where you have a large existing code base that you have refactored using well understood techniques such as extract method and extract superclass until you have a wonderfully clean and consistent application. You will find that even after this refactoring you still have dependencies throughout your code on your logging mechanism that cannot easily be refactored away.

    In software engineering terminology this means that your application code is tightly coupled to whichever logging implementation it uses. This is a bad thing. It makes the application brittle - caveat, see 1 below.

    Aspect Orientated Programming can help solve these sorts of problem by introducing another conceptual level into traditional OO. You can move the common logging code into one or more Aspects. These are separate from the rest of your codebase. When the application is run, the aspects are used to modify the code in your application to, for example, use your preferred logging implementation - oh, and before someone flames me saying I'm wrong, I know that with java this isn't exactly how it works, but it's a useful lie!

    Now the interesting thing about Spring is that it's one of the first widely accepted uses of AOP. I know that even a year ago AOP was mainly of interest to comp-sci academics and bleeding-edge technologists but with Spring incorporating it into the framework it has brought AOP to a lot of people's attention.

    Inversion of control, otherwise known as the Hollywood Principle (don't call us, we'll call you), refers to the currently accepted/hyped practice of "telling things what to do" rather than "things inherently knowing what to do". It's obviously a lot more complex than that, and a lot has been written about the technique but that's the basic gist.

    As for citing major applications that use these practices, well an awful lot of applications are being written using the Spring framework as their heavy lifter of choice. As for Inversion of Control, well-written/architected applications have been using the hollywood principle for years - it really isn't anything new.

    Now, forget all of that and lets talk about Intentional Programming :-P

  12. Demeter shmemeter, I just want to code! by Latent+Heat · · Score: 1
    I had first heard about the Law of Demeter and thought it to be a Good Thing, but lately I wonder.

    In Java Swing, from a JFrame object, you say

    myWidget = new MyWidget(this);

    getContentPane().add(myWidget, BorderLayout.CENTER);

    This is a blatent Demeter violation now, isn't it? Or is it only a Demeter violation of either the strong or the weak form of Demeter depending on whether invoking the function getContentPane() to return an internal object of the JFrame from a derived class is considered OK or not?

    When structured programming came out, it was pretty obvious what kind of mess you had with GOTOs. When Glenford Meyers came out with his "coupling" and "module strength" criterea for function modules, it was pretty obvious what kind of mess you had with global variables or with bundling sets of variables into structs simply to cut down on the parameter lists of functions.

    But with this Law of Demeter business, I am just not seeing what the fuss is, especially when you have to make programs a lot more complex with forwarding functions and convoluted applications of the Visitor pattern to avoid invoking a function on an object contained in another object.

    I mean c'mon people. One of the big uses of object-oriented programming is GUIs, and everyone's GUI has this layered structure of frame object-graphics object-font object where you make some kind of call like myFrame.getGraphics().setFont(myFont). A lot of this is not that the Graphics object is some kind of mystery thing that you have to keep from users of the Frame object, but Frame and Graphics are most likely interfaces to some underlying implementation, and the reason for separate Frame and Graphics interfaces instead of giving Frame forwarding methods to every freakin' method of Graphics is to organize gobs of interface functions in some logical hierarchy.

    1. Re:Demeter shmemeter, I just want to code! by maraist · · Score: 1

      Well, I don't do a lot of GUI design.. Mostly HTML generation through servlets (or some other language structure).

      From that, most of my code is layered separately between UI and application.  In fact all HTML generation comes from JSP pages.. And even more, most of the HTML in that is segregated stle-sheets + JSP2.0-tag files (not to be confused w/ jsp-includes).  And further, the basic framework of a JSP page is built from a sitemesh template (opensymphony.org). which means the content jsp page literally has the most trivial boiler-plate HTML, and body tags.. Just about everything else is abstracted from the content page.. As a result a JSP content page for me (the center-piece of a web page) is only a series of tag-imports, http-request fetches, and invocations of some tag-widgets.

      If I wanted to abstract it one step further, really the JSP page itself is just a customizeble orientation of widgets (like the awt GUI widgets).  I could use an XML file to represent what widgets are used in what fashion.. (Of course the complexity of how many of the widgets are used probably means this isn't practical).  But to some degree, I've used XML descriptions of java beans to define how those beans should be rendered (mapping bean names to widget types and also associating i18n key names all in one place).

      The positive is that I have well formed XML-like structured html, very small components which deal only with the relevent task.. The negative is that these tools aren't very standard (jsp2.0 tag files are very new and I rarely ever see people use them, etc).  Thus there is a serious learning curve to anyone that I hand the project over to.

      The big advantage is I've separated concerns.. The date-time widget is fully self-contained and represents how to render a form field and associated java-script popups necessary to have a full user experience.. As well as tieing in the associated help messages.  There is a minimal coupling.. The widget conforms to an application-specific API of field-descriptive data.  The content jsp page adheres to this same API and knows of the particular types of widgets, but knows nothing about the content itself.  The application (spring-MVC, struts, webwork, etc) cares only about acquiring and processing certain specific pieces of data, and handing them off to the appropriate processing layers (which in tern only care about their relevant dependencies).

      To do the same thing in AWT, you'd need the equivalent of templateable/style-sheetable forms.  You could use factories and mutators configured through IoC.  This allows the entity which wants the functionality of a frame to delegate the rendering to someone else.

      I've always been frustrated that I haven't found an XML description language for java GUIs. 

      --
      -Michael