IOC

243 views
Skip to first unread message

Uberto Barbini

unread,
Aug 25, 2010, 4:02:23 AM8/25/10
to growing-object-o...@googlegroups.com
Hi Nat, Steve,

I noticed that in the GOOS you avoided at all any form of IOC using
always mandatory parameters in the constructor.
As I like IoC (although I don't like most of the IoC frameworks out
there) I'm wondering if it's only for book purposes or do you have bad
feelings about IOC as pattern?


cheers

Uberto

Steve Freeman

unread,
Aug 25, 2010, 4:46:43 AM8/25/10
to growing-object-o...@googlegroups.com
Hi,

I tend to be cautious about IoC containers since some of them seem to lead teams in the wrong direction, and I can't see the point of trying to write code in XML. This is especially true for an application as small as the auction sniper.

Which is not to say that they can never be the right choice.

S.

Steve Freeman

Winner of the Agile Alliance Gordon Pask award 2006
Book: http://www.growing-object-oriented-software.com

+44 (0) 797 179 4105
M3P Limited. http://www.m3p.co.uk
Registered office. 2 Church Street, Burnham, Bucks, SL1 7HZ.
Company registered in England & Wales. Number 03689627

Stephen Haberman

unread,
Aug 25, 2010, 1:38:31 PM8/25/10
to growing-object-o...@googlegroups.com

> I tend to be cautious about IoC containers since some of them seem to
> lead teams in the wrong direction, and I can't see the point of trying
> to write code in XML. This is especially true for an application as
> small as the auction sniper.
>
> Which is not to say that they can never be the right choice.

Ah--that is a refreshing viewpoint, contrasted with the "you must use
an IOC framework" that is pervasive these days.

- Stephen

Nat Pryce

unread,
Aug 25, 2010, 6:22:25 PM8/25/10
to growing-object-o...@googlegroups.com

Oh dear. I'm afraid you've hit my "pedantic about correct use of
technical terminology" nerve!

I'm old enough to remember what IOC really means. And in my day* it
didn't mean "knowing what constructors are for" or "avoiding the new
keyword will magically make code easier to maintain as long as you
never need to understand its dynamic dependencies". Inversion of
Control means callback-driven input, in contrast to having a main loop
that polls the input devices. Think of the difference between DOS and
Windows programming (or curses vs. X11 for Unix programmers). In DOS
you had to write a main loop that queried the position of the mouse
and state of the keyboard. Windows turned that around: it manages the
input devices and calls your program's event handler procedure when
the user performs some input. So Windows inverted the program''s
control flow compared to DOS: it called into the application when
input occurred rather than the application calling out to query device
state .

So, GOOS *only* uses the Inversion of Control pattern: the Smack
library delivers XMPP messages to the application through a callback
and Swing delivers user input events through callbacks.

But I'm being facetious. I believe you're using IOC in its recent
usage as a synonym for Dependency Injection. GOOS does use dependency
injection througout, but we don't call it that because I find the term
"dependency injection" is a really bad name for the pattern.

There are two aspects to Dependency Injection. Firstly, that an
object's interface should define the services that the object
*requires* as well as those it provides. In Java, that's what
constructor parameters are for. Secondly, the code that satisfies the
requirements of an object by giving it a reference to the services of
is collaborators is external to both the object and its collaborators
(for this reason, the pattern also used to be called "third-party
binding" -- some third party is responsible for connecting clients to
services).

The name "Dependency Injection" only refers to the second aspect. And
worse, makes it sound like dependencies are "injected" through the
object's encapsulation boundary rather than explicitly defined as part
of the object's API. And so we get "dependency injection" APIs, like
JavaEE 5, which use reflection to poke dependencies into an object's
private fields, bypassing the constructor, adding a great deal of
complexity to client code and not bringing the benefits that the
Dependency Injection pattern should deliver.

In GOOS we were careful to distinguish between the various practices
that are all lumped together under the term "Dependency Injection".
We define our objects to be context independent (p 54). We clearly
distinguish between an object's dependencies (which must be passed to
the constructor to ensure that the object can never be instantiated in
an invalid state) and its other collaborators (notification listeners,
adjustments) at the object's API (p 52). And we separate the code
that composes objects from the objects being composed (p 64-65).

We don't use a DI framework. Personally, I find them more of a
hindrance than a help in most situations because they don't
distinguish between "internals" & "peers" (p 50) and so often violate
the "composite simpler than the sum of its parts" principle (p 53). I
find that I need to clearly understand, and therefore express in code,
the dependencies between the objects in the system. Hiding that
information away in auto-wiring frameworks or obfuscating it in XML
files that, furthermore, cannot be easily refactored just gets in my
way when I later need to understand the code and modify it. GOOS
instead advocates clearly expressing the dependencies between objects
in the code that composes them, so that the system structure can
easily be refactored, and aggressively refactoring that compositional
code to remove duplication and express intent, and thereby raising the
abstraction level at which we can program (again, p 64-65), so we need
less and less code to write more and more functionality as the system
grows.

The one situation I have found a DI framework useful is when
dynamically loading plug-ins into a running program. But it's not
often I write a program that has to do that, and try to keep that
technical gubbins clearly separated from the code in the application
domain model and elsewhere in the system.

--Nat

* Windows 3.0 programming, if you must know. And be very thankful if
you've never had to do that!

--
http://www.natpryce.com

Matt Wynne

unread,
Aug 25, 2010, 6:27:53 PM8/25/10
to growing-object-o...@googlegroups.com
Well said that man!

Please copy / paste that in a blog post for posterity, Nat. To great to leave dangling around in a mailing list.

cheers,
Matt

http://blog.mattwynne.net
+44(0)7974 430184

Gishu Pillai

unread,
Aug 26, 2010, 12:33:13 AM8/26/10
to growing-object-o...@googlegroups.com
+1 for calling a spade a spade.
In most cases, designing your code such that collaborators can be injected for testability - goes a long way. As you said, the cases where DI Frameworks are absolutely needed is where you need to dynamically load and activate plug-in like behavior. Usually the complexity they drag (you need to learn their xml-configuration-variant) is not worth it.

Matteo Vaccari

unread,
Aug 26, 2010, 3:18:15 AM8/26/10
to growing-object-o...@googlegroups.com


Hi Uberto, keep asking questions, as long as you obtain such informative answers for all of us :-)

Matteo

Moandji Ezana

unread,
Aug 26, 2010, 3:56:26 AM8/26/10
to growing-object-o...@googlegroups.com
While IoC frameworks can be overkill, they are very useful when dependencies have lots of different scopes. And good ones don't make you abandon constructor injection or use XML.

Moandji

Nat Pryce

unread,
Aug 26, 2010, 4:00:41 AM8/26/10
to growing-object-o...@googlegroups.com
What do you mean by "scope" in this case, compared to Java's lexical
scoping?

www.natpryce.com

Moandji Ezana

unread,
Aug 26, 2010, 4:21:54 AM8/26/10
to growing-object-o...@googlegroups.com
On Thu, Aug 26, 2010 at 10:00 AM, Nat Pryce <nat....@gmail.com> wrote:
What do you mean by "scope" in this case, compared to Java's lexical
scoping?

I meant application-level scopes, such as application, request, session, prototype...

I've never tried to implement an ad-hoc injection system that knows when to create new instances depending on their scope, so I don't know how hard it is, but a framework like Guice (which I much prefer to Spring) does it very well.

Moandji

Dan Haywood

unread,
Aug 26, 2010, 5:06:47 AM8/26/10
to growing-object-o...@googlegroups.com
Yes, JSR-299 (Weld reference implementation) also does this very nicely.

To add to the point about scopes; it's kind-a obvious that a session-scope instance can be injected into a request-scope instance, because the session is the "parent" of the request... but a nice trick that JSR-299 has is that it also allows for a request-scope instance to be injected into a session-scope instance.  How?  Well, it uses a bit of bytecode proxying (javassist in the case of Weld) so that when called the proxy dispatches to the "current" request-scope instance.

What's I find interesting is that the annotation that defines how an instance is scoped is applied to the implementation, not the interface.  And I guess that's correct: the programmer is describing how the implementation can be used (cf whether is thread-safe).

None of this goes against GOOS, though... you can inject into constructors or into setters, and so the mandatory constructors/set adjustments/add peers pattern (is there a name for that?) which GOOS describes works fine.

Dan
dkhaywood.vcf

David Peterson

unread,
Aug 26, 2010, 5:22:49 AM8/26/10
to growing-object-o...@googlegroups.com
I'm not sure I agree that it's right to annotate classes with things like scope. To me that's a configuration detail not an implementation detail. If you tag a class in Google Guice with a @Singleton annotation that feels wrong to me. It's up to the user how many instances they want to create. Spring JavaConfig (i.e. configuration in Java, not XML) is better than Guice, in this respect at least, and is my preferred IoC framework. It also gives you an easy path to switch from Spring XML as you can use both config styles simultaneously.

David

Uberto Barbini

unread,
Aug 26, 2010, 5:38:56 AM8/26/10
to growing-object-o...@googlegroups.com
> the user performs some input.  So Windows inverted the program''s
> control flow compared to DOS: it called into the application when
> input occurred rather than the application calling out to query device
> state .

Never done DOS graphic programming, but in games we still use the same
pattern! :)

> So, GOOS *only* uses the Inversion of Control pattern: the Smack
> library delivers XMPP messages to the application through a callback
> and Swing delivers user input events through callbacks.

:)

> There are two aspects to Dependency Injection.  Firstly, that an
> object's interface should define the services that the object
> *requires* as well as those it provides. In Java, that's what
> constructor parameters are for.

mmmh I agree on the first part but not on the second.
Constructor parameters have lots of limitation in Java, and you need
constructors without parameters for any object that could be
persisted.
Ideally I'd prefer a way to declare required services. Annotations are
a acceptable compromise.
But this is only my feelings.

> (for this reason, the pattern also used to be called "third-party
> binding" -- some third party is responsible for connecting clients to
> services).

First time I heard this name: much better IMHO than IOC or DI.

> The name "Dependency Injection" only refers to the second aspect.  And
> worse, makes it sound like dependencies are "injected" through the
> object's encapsulation boundary rather than explicitly defined as part
> of the object's API.  And so we get "dependency injection" APIs, like
> JavaEE 5, which use reflection to poke dependencies into an object's
> private fields, bypassing the constructor, adding a great deal of
> complexity to client code and not bringing the benefits that the
> Dependency Injection pattern should deliver.

agreed 100%

> In GOOS we were careful to distinguish between the various practices
> that are all lumped together under the term "Dependency Injection".
> We define our objects to be context independent (p 54).  We clearly
> distinguish between an object's dependencies (which must be passed to
> the constructor to ensure that the object can never be instantiated in
> an invalid state) and its other collaborators (notification listeners,
> adjustments) at the object's API (p 52).  And we separate the code
> that composes objects from the objects being composed (p 64-65).

I got it now.
In the book examples I agree that any form of IOC framework would be
an overkill, still in big application we found them useful.

Could be that our design is not as good as yours (well for sure it
isn't) but in one of our application we have:
CommandSaveInvoice (from CommandPattern) which requires:
InvoiceManager (for messages and validation)
InvoiceDao (from Dao pattern)
ClientDao
ProductDao
every Dao also require a reference to PersistenceManager and some
drivers for DbVersion and Encryption

Now, we can put Builders for all those classes but having Guice that
declaratively does the work for us it reduce our classes and simplify
the code (we can specify when use a simple new and when a specific
factory for the object).
The other use is in tests is very simple to say to guicemodule to use
mocked dao instead of real ones and be able to test the Commands, same
as we used constructor parameters.

To be honest lately I'm feeling like Guice is following the same path
of other frameworks and becoming more and more heavy, but it's still
very light.
what we really need it could be probably done with just a dozen of classes.

> way when I later need to understand the code and modify it.  GOOS
> instead advocates clearly expressing the dependencies between objects
> in the code that composes them, so that the system structure can
> easily be refactored, and aggressively refactoring that compositional
> code to remove duplication and express intent, and thereby raising the
> abstraction level at which we can program (again, p 64-65), so we need
> less and less code to write more and more functionality as the system
> grows.

maybe we are not good enough for this... I fear lots of classes with
very tight integration and very little refactoring, because it's hard
and because we are always in a hurry...
The team has still problems to use TDD in the real application. Guice
could be a not so bad helper to declare required services (instead of
monster classes).

cheers

Uberto

Moandji Ezana

unread,
Aug 26, 2010, 6:00:00 AM8/26/10
to growing-object-o...@googlegroups.com
On Thu, Aug 26, 2010 at 11:22 AM, David Peterson <pete...@gmail.com> wrote:
I'm not sure I agree that it's right to annotate classes with things like scope. To me that's a configuration detail not an implementation detail. If you tag a class in Google Guice with a @Singleton annotation that feels wrong to me. It's up to the user how many instances they want to create.

It's an implementation detail (and not a configuration detail) because you can't, for example, store request-specific state in a singleton. So, if you expect a class to be request-scoped, you code it differently than if you expect it to be a singleton or in session or prototype scope.

If someone decides to configure your wiring differently, odds are the application won't work correctly any more, so it's not up to the user how many instances to create.

Spring JavaConfig (i.e. configuration in Java, not XML) is better than Guice, in this respect at least

I haven't used JavaConfig much, but you can use Guice without annotations and do everything in the binding module. 

Moandji

Dan Haywood

unread,
Aug 26, 2010, 6:09:20 AM8/26/10
to growing-object-o...@googlegroups.com
On 26/08/2010 10:22, David Peterson wrote:
I'm not sure I agree that it's right to annotate classes with things like scope.
Then I think you're arguing with the JSR-299 spec, and JSR-330 too, which is similar.  And JSR-330 had Bob Lee and Rod Johnson as its leads, didn't it, who have pretty decent reputations (not that you don't, David!)



To me that's a configuration detail not an implementation detail. If you tag a class in Google Guice with a @Singleton annotation that feels wrong to me. It's up to the user how many instances they want to create.

I see it more in terms of the programmer defining a constraint: this object should not be instantiated more than once, or per session, or per scope.  If there's no annotation, then in both JSR-299 and JSR-330 the object will be instantiated each time an instance is needed ... which makes sense to me, cos there's no constraint.

Said in these terms the "IOC container" is taking the responsibility of enforcing these constraints.  Which I think is right; why should the user of the dependency have to know whether the implementation is thread-safe or not?  It just wants an appropriate object to collaborate with.



 Spring JavaConfig (i.e. configuration in Java, not XML) is better than Guice, in this respect at least, and is my preferred IoC framework. It also gives you an easy path to switch from Spring XML as you can use both config styles simultaneously.
I like the XML of Spring for visualization (spring-beans), though I think that Guice is going to have something on this too, and I'm sure ultimately we'll see something for Weld too.  Otherwise though I prefer the typesafety of JSR-299/330.

Dan
dkhaywood.vcf

Steve Freeman

unread,
Aug 26, 2010, 12:28:50 PM8/26/10
to growing-object-o...@googlegroups.com
On 26 Aug 2010, at 11:38, Uberto Barbini wrote:
> Could be that our design is not as good as yours (well for sure it
> isn't) but in one of our application we have:
> CommandSaveInvoice (from CommandPattern) which requires:
> InvoiceManager (for messages and validation)
> InvoiceDao (from Dao pattern)
> ClientDao
> ProductDao
> every Dao also require a reference to PersistenceManager and some
> drivers for DbVersion and Encryption

Could you replace all those 'Dao's and 'Manager's with domain terms. For example, is an 'InvoiceDao' a 'Ledger'? It's amazing what a difference it makes to the code.

> maybe we are not good enough for this... I fear lots of classes with
> very tight integration and very little refactoring, because it's hard
> and because we are always in a hurry...

if it doesn't have to work well, you can go as fast as you like :)

> The team has still problems to use TDD in the real application. Guice
> could be a not so bad helper to declare required services (instead of
> monster classes).

You shouldn't be seeing monster classes. On the whole, you should get more locality as you discover intermediate objects that cluster up the creation of domain objects.

S.

Nat Pryce

unread,
Aug 26, 2010, 5:23:04 PM8/26/10
to growing-object-o...@googlegroups.com

I prefer to just instantiate objects and pass the dependencies to
their constructors. Whether it's a servlet or a domain object, I find
that makes code easier to understand and change.

I can see that a DI framework might help work around the fact that the
Servlet API makes it much harder to manage dependencies than it should
be. But I prefer to work around that by just avoiding those aspects
of the Servlet API, either by using a better HTTP server library, like
SimpleWeb, or by giving my servlets constructors and running them in
an embedded servlet engine like Jetty -- using JavaEE as a collection
of useful libraries rather than a surrogate operating system.

I've been surprised how much code I could get rid of just by giving
servlets constructors and passing them the objects they needed. Even
in a small web-app with a couple of servlets that use a few shared
objects, using constructors cut out several hundred lines of pointless
XML configuration and code that did nothing but put things into
various contexts in one part of the code and get things back out in
another part of the code. Totally pointless because Java already does
a pretty good job of defining and managing scopes itself.

--Nat

--
http://www.natpryce.com

Nat Pryce

unread,
Aug 26, 2010, 5:27:03 PM8/26/10
to growing-object-o...@googlegroups.com
On 26 August 2010 10:38, Uberto Barbini <ube...@ubiland.net> wrote:
> Constructor parameters have lots of limitation in Java,

What limitations?

> you need
> constructors without parameters for any object that could be
> persisted.

Not necessarily. If a library forces that, it's not a very good
persistence library.

For example, you don't need to define a no-arg constructor to
serialise objects with Java serialisation or XStream. In Hibernate you
can define a Tupleizer to instantiate an object either by calling the
class' constructor or by using Objenesis to bypass the constructor
entirely. Or, if you don't want to do that, you can make the no-arg
constructor private so that it is only used by the persistence library
and that design wart doesn't pollute the rest of your domain model.

--Nat


--
http://www.natpryce.com

Uberto Barbini

unread,
Aug 27, 2010, 4:25:05 AM8/27/10
to growing-object-o...@googlegroups.com
> Could you replace all those 'Dao's and 'Manager's with domain terms. For example, is an 'InvoiceDao' a 'Ledger'? It's amazing what a difference it makes to the code.
.
DAOs are just wrappers on the persistence layer internals.
Theoretically changing dao impl we can switch from bigtable to file
system to dbms.
"Managers" is just a common terms for Ledger, EmailSender, xxxxer, etc.

>> maybe we are not good enough for this... I fear lots of classes with
>> very tight integration and very little refactoring, because it's hard
>> and because we are always in a hurry...
>
> if it doesn't have to work well, you can go as fast as you like :)

well... all in all it's working pretty well. :)
It's not that we don't have time to refactor, the problem is that is
not easy what you're asking for.
We cannot change our team, they are also good programmers, just used
to work with "brain half switched off and googling for technical
solutions". On the other side they are pretty good on domain related
problems.
From my experience this is far from atypical and it takes time to
change this attitude.
This is a bit OT anyway. :)


cheers

Uberto

Moandji Ezana

unread,
Aug 27, 2010, 4:38:09 AM8/27/10
to growing-object-o...@googlegroups.com
On Fri, Aug 27, 2010 at 10:25 AM, Uberto Barbini <ube...@ubiland.net> wrote:
Theoretically changing dao impl we can switch from bigtable to file system to dbms.

I find this *very* theoretical. Moving from one RDBMS to another is one thing, moving from a RDMS to, say, BigTable generally requires a far broader rethink of how the system as a whole accesses data.

Moandji

Steve Freeman

unread,
Aug 27, 2010, 4:48:12 AM8/27/10
to growing-object-o...@googlegroups.com
On 27 Aug 2010, at 10:25, Uberto Barbini wrote:
>> Could you replace all those 'Dao's and 'Manager's with domain terms. For example, is an 'InvoiceDao' a 'Ledger'? It's amazing what a difference it makes to the code.
> .
> DAOs are just wrappers on the persistence layer internals.
> Theoretically changing dao impl we can switch from bigtable to file
> system to dbms.
> "Managers" is just a common terms for Ledger, EmailSender, xxxxer, etc.

Not sure I got the point across. I know what a DAO and Manager is supposed to represent, but they're generic terms from the domain of implementation. I've seen code based improve radically by insisting on real domain terminology and banning all such terms--except at the edges. Using the right words throws up any inconsistencies in the structure of the code.

> It's not that we don't have time to refactor, the problem is that is
> not easy what you're asking for.
> We cannot change our team, they are also good programmers, just used
> to work with "brain half switched off and googling for technical
> solutions". On the other side they are pretty good on domain related
> problems.
> From my experience this is far from atypical and it takes time to
> change this attitude.
> This is a bit OT anyway. :)

This is all too true. And I don't work that way any more because I've seen the trouble it causes down the road.

Uberto Barbini

unread,
Aug 27, 2010, 6:40:47 AM8/27/10
to growing-object-o...@googlegroups.com
> Not necessarily.  If a library forces that, it's not a very good
> persistence library.
>
> For example,  you don't need to define a no-arg constructor to
> serialise objects with Java serialisation or XStream. In Hibernate you
> can define a Tupleizer to instantiate an object either by calling the
> class' constructor or by using Objenesis to bypass the constructor
> entirely.  Or, if you don't want to do that, you can make the no-arg
> constructor private so that it is only used by the persistence library
> and that design wart doesn't pollute the rest of your domain model.

mmmh ok. But anyway this is not the point.

Any hald decent IOC framework can pass dependences on constructor or
later on fields.
What I haven't very clear is how to pass dependences of dependences etc....
For example if for the SaveInvoice command I need InvoiceLedger and
for InvoiceLedger I need PersistenceManager (singleton) and
EmailSender and for the latter I need the ConfigurationService
(singleton) which kind of code I have to write to process that
command?

public SaveInvoice commandSaveInvoiceFactory(){
EmailSender emailSender = new
EmailSender(ConfigurationService.getInstance());
invoiceLedger = new
InvoiceLedger(PersistenceManager.getInstance(), emailSender);

return new SaveInvoice(InvoiceLedger);

}


does it make sense or am I talking rubbish?

cheers

Uberto

rhys

unread,
Aug 27, 2010, 7:47:23 AM8/27/10
to Growing Object-Oriented Software
You don't need a whizzy JSR framework to do any of this. Just use
plain old objects, at least to start with.

Request scoped objects should be passed around as parameters. Create
these at the beginning of a request using a factory, which can pass in
persistence/email/notification services. Get rid of .getInstance() and
use constructor parameters.

Uberto Barbini

unread,
Aug 27, 2010, 7:50:42 AM8/27/10
to growing-object-o...@googlegroups.com
can you write the pseudo code?
It's not that I need a framework, I think I need a centralized binder module.

cheers

Uberto

Moandji Ezana

unread,
Aug 27, 2010, 8:18:46 AM8/27/10
to growing-object-o...@googlegroups.com
On Fri, Aug 27, 2010 at 1:47 PM, rhys <rhyske...@gmail.com> wrote:
Request scoped objects should be passed around as parameters.

I disagree. Object interaction is a lot nicer when scopes are managed in a detailed way. At least, that's what I've found using Guice (and thinking about the scope of each object) vs. Spring with everything as a singleton. Of course, you can do the same with Spring, but in my experience, Spring's singleton-by-default approach makes people forget about scopes altogether, whereas Guice's prototype-by-default forces the question of whether you want an instantiation on every injection or not.

Moandji

Nat Pryce

unread,
Aug 27, 2010, 10:05:04 AM8/27/10
to growing-object-o...@googlegroups.com
I think you're misusing the term "singleton". In Spring, if you ask it to create an object, it creates an object. Within the scope that the object is defined, you can refer to that object by it's name. Spring does not create a global access point for the type. If you create another instance of the same type, you get another distinct instance.

Just creating one instance of a class does not make that class a singleton.    

Moandji Ezana

unread,
Aug 27, 2010, 10:54:55 AM8/27/10
to growing-object-o...@googlegroups.com
On Fri, Aug 27, 2010 at 4:05 PM, Nat Pryce <nat....@gmail.com> wrote:
I think you're misusing the term "singleton".

I'm using it the same way Spring does. Granted, it's not a Singleton in the Gang of Four sense, but Spring does guarantee that as long as you stay within its confines, there will only be one instance of that type.

What term should be used instead to designate a singleton scope?

Moandji

Nat Pryce

unread,
Aug 27, 2010, 12:09:47 PM8/27/10
to growing-object-o...@googlegroups.com
Don't you mean "one instance with that name"? 

In Spring, if I declare two "beans" of the same type but with different names I get two different instances, not two references to the same instance. It's the same as creating an object with the new keyword & storing the reference in a variable.

Stephen Haberman

unread,
Aug 27, 2010, 4:52:16 PM8/27/10
to growing-object-o...@googlegroups.com

> What I haven't very clear is how to pass dependences of dependences
> etc....

I've been solving this lately with a non-singleton Registry that is an
explicit interface for application-scoped beans.

A typical use case I use this for is something like:

* a parent view has 4 tabs
* tab1 wants application-scope bean A
* tab2 wants application-scope bean A and B
* tab3 ... etc.

So, when instantiating each tab, if the parent view has to know all the
beans its children care about, the parent gets constructor bloat of
useless-to-it beans that it just passes on.

Instead, I have an interface:

interface AppRegistry {
BeanA getBeanA();
BeanB getBeanB();
}

That functions a lot like a spring app context, but with an explicit
interface, and no magical runtime-lookup "get(SomeBean.class)" method.

ParentView's cstr is then:

ParentView(AppRegistry r, ...)

And the tab cstrs are:

TabA(AppRegistry r, nonAppScopeBeanC c) {
a = r.getBeanA();
}
TabB(AppRegistry r) {
a = r.getBeanA();
b = r.getBeanB();
}

It all works out rather nicely--the biggest downside is that it is no
longer clear what TabA/TabB dependent on, at least more granularly than
"some number of app-scoped beans".

In practice I haven't found this to be a big deal but would appreciate
any feedback on a better way to go about it.

- Stephen

Lance Walton

unread,
Aug 27, 2010, 5:08:40 PM8/27/10
to growing-object-o...@googlegroups.com
You could solve the 'only downside' bit by making the AppRegistry interface extend a bunch of interfaces (one per Tab) each of which declared just what the Tab needed.

Stephen Haberman

unread,
Aug 27, 2010, 8:48:19 PM8/27/10
to growing-object-o...@googlegroups.com

> You could solve the 'only downside' bit by making the AppRegistry
> interface extend a bunch of interfaces (one per Tab) each of which
> declared just what the Tab needed.

:-)

I'd considered that, as I'd noticed some of the "MVP" GWT stuff uses
inner interfaces, though in a slightly different way.

But, yeah, something like:

public class TabA {
public interface Deps {
getBeanA();
getBeanB();
}
public TabA(TabA.Deps deps) {
...
}
}

I'd forgotten about that though--thanks for mentioning it!

Out of curiosity, would you have the TabA.Deps interface only
include application scoped dependencies, or potentially other
scopes as well?

(I haven't really done much formalization around any scope
other than the application one.)

- Stephen

Lance Walton

unread,
Aug 28, 2010, 3:36:28 AM8/28/10
to growing-object-o...@googlegroups.com
On 28 Aug 2010, at 01:48, Stephen Haberman wrote:

>
>> You could solve the 'only downside' bit by making the AppRegistry
>> interface extend a bunch of interfaces (one per Tab) each of which
>> declared just what the Tab needed.
>
> :-)
>
> I'd considered that, as I'd noticed some of the "MVP" GWT stuff uses
> inner interfaces, though in a slightly different way.
>

I probably wouldn't do it as an inner interface, since I mostly dislike them and prefer creating new packages instead.


> I'd forgotten about that though--thanks for mentioning it!
>
> Out of curiosity, would you have the TabA.Deps interface only
> include application scoped dependencies, or potentially other
> scopes as well?
>
> (I haven't really done much formalization around any scope
> other than the application one.)

Me neither. I don't know, but I suspect I'd separate them.

>
> - Stephen
>

Steve Freeman

unread,
Aug 28, 2010, 5:09:15 AM8/28/10
to growing-object-o...@googlegroups.com
So what about if you have tab builders, each of which knows what it needs to construct? Then you can register the relevant tab builders with the view which does not need to know what's inside.

S.

On 27 Aug 2010, at 22:52, Stephen Haberman wrote:
>
>> What I haven't very clear is how to pass dependences of dependences
>> etc....
>
> I've been solving this lately with a non-singleton Registry that is an
> explicit interface for application-scoped beans.
>
> A typical use case I use this for is something like:
>
> * a parent view has 4 tabs
> * tab1 wants application-scope bean A
> * tab2 wants application-scope bean A and B
> * tab3 ... etc.

Steve Freeman

Stephen Haberman

unread,
Aug 28, 2010, 9:54:01 PM8/28/10
to growing-object-o...@googlegroups.com

> So what about if you have tab builders, each of which knows what it
> needs to construct? Then you can register the relevant tab builders
> with the view which does not need to know what's inside.

True, the view does not know what's inside the builder, but somebody has to,
and wiring together the resulting builder code by hand is, IMO, what pushes
people to auto-wiring DI frameworks.

For example, using guice-terminology of suppliers instead of builders:

class TabA {
public TabA(appBeanA, requestBeanB) {
...
}
}

class TabASupplier {
pirvate appBeanA;
public TabASupplier(appBeanA) {
this.appBeanA = appBeanA;
}
public TabA create(requestBeanB) {
return new TabA(appBeanA, requestBeanB);
}
}

Now, the parent view:

class ParentA {
private TabASupplier tabASupplier;
public ParentA(tabASupplier) {
this.tabASupplier = tabASupplier;
}
void businessLogic() {
tabASupplier.create(requestBeanB);
}
}

class ParentASupplier {
private TabASupplier tabASupplier;
public ParentASupplier(tabASupplier) {
this.tabASupplier = tabASupplier;
}
public ParentA create() {
return new ParentA(tabASupplier);
}
}

So whoever instantiates the ParentASupplier is going to have to know about the
TabASupplier...which is going to have to know about any suppliers that TabA
wants, recursing all the way down the control flow.

This leads to an explosion of supplier wiring code in the application startup
sequence where the top-level entry point is handed a single FooSupplier, that
seems simple to use (just call `create`), but it required references to every
other supplier in the app to put that one FooSupplier instance together.

Which is why people think they need guice to do all of that wiring for them.

I think anyway--let me know if I missed something.

(...re-reading this, these are really factories--I wonder why guice choose
to introduce a new term, if not to just avoid the conceptual legacy baggage
of "factories == bad".)

- Stephen


Stephen Haberman

unread,
Aug 28, 2010, 10:03:11 PM8/28/10
to growing-object-o...@googlegroups.com

> > (I haven't really done much formalization around any scope other
> > than the application one.)
>
> Me neither. I don't know, but I suspect I'd separate them.

Thinking about it more, I agree, I would separate them too.

While I have not had explicitly named AppRegistry, SessionRegistry,
RequestRegistry interfaces, I have occasionally have RequestContext
interfaces, which s/Registry/Context/, they are really the same thing.

I stick with the Registry terminology mostly as a tribute to Fowler's
PoEAA [1], but also to be contrary.

(Admittedly, I started (ab)using registries as statics and relatively
recently changed my style [2] to passing them around explicitly.)

- Stephen

[1]: http://martinfowler.com/eaaCatalog/registry.html
[2]: http://www.draconianoverlord.com/2010/01/15/changing-my-style.html
(Huh--I had completely forgotten how of much of this AppRegistry style I
had written up in this post.)

Nat Pryce

unread,
Aug 29, 2010, 5:25:04 AM8/29/10
to growing-object-o...@googlegroups.com
On 29 August 2010 02:54, Stephen Haberman <ste...@exigencecorp.com> wrote:
> This leads to an explosion of supplier wiring code in the application startup
> sequence where the top-level entry point is handed a single FooSupplier, that
> seems simple to use (just call `create`), but it required references to every
> other supplier in the app to put that one FooSupplier instance together.

Which shows that the code is violating the "Composite is Simpler than
the Sum of its Parts" principle.

I'd interpret that as a "design pressure" pushing me to do something
to improve the structure of the system to better hide information and
factor out more appropriate higher-level abstractions.

> Which is why people think they need guice to do all of that wiring for them.

Which is just sweeping the problems under the rug. And rug that ends
up with an ever-increasing bulge in the middle where all the dirt is
accumulating.

--Nat

--
http://www.natpryce.com

Uberto Barbini

unread,
Aug 29, 2010, 7:41:03 AM8/29/10
to growing-object-o...@googlegroups.com
>> Which is why people think they need guice to do all of that wiring for them.
>
> Which is just sweeping the problems under the rug. And rug that ends
> up with an ever-increasing bulge in the middle where all the dirt is
> accumulating.

If I understood correctly:
Let's forget a moment about guice, let's call it "binder with a
registry module" BRM in short.
Let's forget about annotations: let's use BRM to pass the correct
instantiated services to constructors.

The remaining problem is that this could be a incentive to abuse of
anonymous registered services instead of carefully choosing the one
best suited for the domain.
Like in the "managers/dao" naming.
Did I understand it correctly?

cheers

Uberto

Stephen Haberman

unread,
Sep 7, 2010, 12:39:27 AM9/7/10
to growing-object-o...@googlegroups.com

> Otherwise though I prefer the typesafety of JSR-299/330.

Somewhat of a tangent, but is any auto-wiring DI really type safe?

You declare your dependencies via @Inject-annotated cstrs, then your
bindings of how these dependencies are satisfied somewhere else, and
then at runtime magic happens and the framework calls your cstrs via
reflection.

That your cstr dependencies are all correctly met by your bindings is
something that is only vetted at runtime.

Per the Weld documentation [1]:

At system initialization time, the container must validate that
exactly one bean exists which satisfies each injection point.

To me, using the term "type safe" == "the compiler will tell me if I
screw up", not "the framework will tell me at runtime".

- Stephen

[1]: http://docs.jboss.org/weld/reference/1.1.0.Beta1/en-US/html_single/

Erich Oswald

unread,
Sep 8, 2010, 8:49:47 AM9/8/10
to growing-object-o...@googlegroups.com
"Type-safe" means that the injected object is compatible with the
static type of the reference. It's perfectly possible that multiple
candidates (or none) conform to these type constraints, leading to the
situation that the DI container doesn't know which one to choose.

How would the compiler know how many candidates for injection you will
have on your classpath at runtime? The compiler only has a static view
of the world. In general it also doesn't know if a reference is null
when you access an object. "type safe" == "the compiler will tell me
if I screw up" is rather simplistic in that regard.

- Erich

Stephen Haberman

unread,
Sep 9, 2010, 12:44:01 AM9/9/10
to growing-object-o...@googlegroups.com

> "Type-safe" means that the injected object is compatible with the
> static type of the reference.

If I follow correctly, you're saying if I inject Bar:

public Foo(Bar bar) { ... }

The instance `bar` that is injected will satisfy the static type of
`Bar`. Sure, but hasn't that always been the case with DI?

My impression was that "type safe DI" was a new term coined by the
Guice guys. Dan's comment that JSR-299 is type safe whereas Spring
is not piqued my interest and garnered my reply.

> How would the compiler know how many candidates for injection you will
> have on your classpath at runtime? The compiler only has a static view
> of the world.

Exactly.

That's why calling auto-wiring DI "type safe" makes no sense to me. The
runtime wiring is not at all type-safe. Which is fine, I understand why
it's not. But given that runtime wiring is the very purpose of auto DI
frameworks, why do people keep calling them "type safe"?

> "type safe" == "the compiler will tell me if I screw up" is rather
> simplistic in that regard.

Very true--I admit this was an overstatement. I should have keep the
statement simply as the compiler will catch `new Foo(wrongArgHere)` but
auto DI will not catch `new Foo(argNotBound)`.

- Stephen

Stephen Haberman

unread,
Sep 9, 2010, 1:02:22 AM9/9/10
to growing-object-o...@googlegroups.com

(Apologies for the self-reply.)

> But given that runtime wiring is the very purpose of auto DI
> frameworks, why do people keep calling them "type safe"?

I have been reading about why Guice would claim type safety, and it
seems to be mostly because previously Spring was so horribly un-type
safe (string identifiers, XML, etc.).

Guice did a lot to make isolated user code type safe, and isolated
binding code type safe--it's just the runtime resolution/constructor
calls that are not type safe.

Dunno. I guess I see where they are coming from. But it still bothers
me.

- Stephen

Erich Oswald

unread,
Sep 9, 2010, 3:34:17 AM9/9/10
to growing-object-o...@googlegroups.com
On 09.09.10 07:02, Stephen Haberman wrote:
>
> (Apologies for the self-reply.)
>
>> But given that runtime wiring is the very purpose of auto DI
>> frameworks, why do people keep calling them "type safe"?
>
> I have been reading about why Guice would claim type safety, and it
> seems to be mostly because previously Spring was so horribly un-type
> safe (string identifiers, XML, etc.).

That makes sense. Guice also offers a type-safe way to qualify
multiple objects that would fit the static type. All you need to do is
define the necessary annotations. I have to admit that I'm not sure
it's the right way to go. Looking at a few CDI examples in JEE6 made
me scratch my head.

> Guice did a lot to make isolated user code type safe, and isolated
> binding code type safe--it's just the runtime resolution/constructor
> calls that are not type safe.

It seems you want type-safety to imply that you don't have to wait
until runtime to find out that something is wrong. My impression is
that you're asking for more than type-safety is meant to guarantee.

> Dunno. I guess I see where they are coming from. But it still bothers
> me.
>
> - Stephen
>

- Erich

Moandji Ezana

unread,
Sep 9, 2010, 4:42:50 AM9/9/10
to growing-object-o...@googlegroups.com
On Thu, Sep 9, 2010 at 7:02 AM, Stephen Haberman <ste...@exigencecorp.com> wrote:
it's just the runtime resolution/constructor calls that are not type safe

With Guice, you can't inject the wrong type, but you can forget to bind an interface to an implementation, for example. It's the DI equivalent of a null pointer. Arguably, null pointers are a hole in the type system, but that's not DI-specific.

Moandji

Guilherme Silveira

unread,
Jan 6, 2011, 11:00:16 AM1/6/11
to growing-object-o...@googlegroups.com

Hello there,


> I've been surprised how much code I could get rid of just by giving servlets constructors and passing them the objects they needed.  

I believe Paul Hammant was working on Jetty supporting servlets with constructors back in 2006, the exact way you mentioned... seemed great,its just sad it took forever for it to become popular - and it still did not.

> using constructors cut out several hundred lines of pointless XML configuration

Comparing anything with XML configuration is cheating :) I remember when Joe Walnes said that configuration should be first programmatic, and then, well, then anything else that *might* help. The key feature of a software would be to be *easily* configurable through its API. IMHO configuring the system is the same as "configuring our component composition".

> I prefer to just instantiate objects and pass the dependencies to their constructors.  Whether it's a servlet or a domain object, I find that makes code easier to understand and change.

I believe that's how most of XStream internals work. Dependencies are instantiated "by hand" and passed to constructors

Nat, you mentioned the DI framework takes out the visibility that you have with "by hand" wiring dependencies, which I agree. The thought that "now I dont need to know who depends on who" because the frameworks makes that decision is not true because we need to know how the framework takes those decisions. And the negative side is that its hidden from us. I agree frameworks lack on that visibility. Wiring by hand still gives me IoC, but I know what is happenning because its clear code written in wiring parts of my software. ++ on that.

Those frameworks (ignore xml or member variable setting based ones) could expose the dependency tree somehow. It seems like this feature would help bringing back visibility on how things are connected, but not allowing me to easily play with composing the behavior.

About the scopes, I agree the question should not be in those cases about them. To create a new scope simply create a new object and compose your system as required. But the question is about lifespan and lifecycle.... handling it by hand, how would it look like? Let me try an example, I will go step by step.


Basic server startup:

class MyApp

  pool = new MyConnectionPool()

  new Server(pool).start()


My services are stateless, request lifespan, so:

class MyApp

  pool = new MyConnectionPool();

  services = new Services(pool);

  new Server(services).start()


The next step is to add my URI bindings, and whichever one needs to access a connection, the lifecycle of a connection will be handled by the services class, as with any other "request" lifespan component.

class MyApp

  pool = new MyConnectionPool();

  services = new Services(pool);

  services.add("/first", First.class);

  services.add("/second", Second.class);

  services.add("/third", Third.class);

  new Server(services).start()


And now handling something that lives more than one request, i.e. a logged in user:

class MyApp

  pool = new MyConnectionPool();  // app lifespan

  users = new Users(pool); // between one request lifespan and the app lifespan

  services = new Services(pool, users);

  services.add("/first", First.class);

  services.add("/second", Second.class);

  services.add("/third", Third.class);

  new Server(services).start()


Or should I pass the users to Server (as its in a larger picture?).

BTW I was trying to run away from "pattern based" names, like "Services". What should I rename it to? Or better, refactor those classes into?


Regards

Guilherme Silveira

Matteo Vaccari

unread,
Jan 8, 2011, 10:54:56 AM1/8/11
to growing-object-o...@googlegroups.com

The next step is to add my URI bindings, and whichever one needs to access a connection, the lifecycle of a connection will be handled by the services class, as with any other "request" lifespan component.

class MyApp

  pool = new MyConnectionPool();

  services = new Services(pool);

  services.add("/first", First.class);

  services.add("/second", Second.class);

  services.add("/third", Third.class);

  new Server(services).start()



I suppose the intent is that the services object instantiates a First, Second etc objects, is that right?  But now you can't pass collaborators to these new objects.  This is how a servlet engine works, and it's the reason why servlets must have a zero-args constructor.  I don't like this!

Don't know which is the "purest" way to solve this problem (i.e., the problem of passing collaborators to several "controller" objects that handle an url prefix.)  My usual solution is to create a single servlet per project, with a single "service()" method, and regard that "service()" as my "main" function.  In that service() I create objects and link them together.

Another solution might be to pass factories instead of class objects.  That sounds a bit more complicated though.

And now handling something that lives more than one request, i.e. a logged in user:

class MyApp

  pool = new MyConnectionPool();  // app lifespan

  users = new Users(pool); // between one request lifespan and the app lifespan


If we are talking about a web application, I really don't like this design.  I don't want User objects to live beyond a single request.  If I need to know stuff about the logged-in user I will load that from session storage at every request. 

Disclaimer: this is how *I* do things. YMMV.

Matteo


Giorgio Sironi

unread,
Jan 9, 2011, 6:28:55 AM1/9/11
to growing-object-o...@googlegroups.com
On Sat, Jan 8, 2011 at 4:54 PM, Matteo Vaccari <vac...@pobox.com> wrote:
> I suppose the intent is that the services object instantiates a First,
> Second etc objects, is that right?  But now you can't pass collaborators to
> these new objects.  This is how a servlet engine works, and it's the reason
> why servlets must have a zero-args constructor.  I don't like this!
>
> Don't know which is the "purest" way to solve this problem (i.e., the
> problem of passing collaborators to several "controller" objects that handle
> an url prefix.)  My usual solution is to create a single servlet per
> project, with a single "service()" method, and regard that "service()" as my
> "main" function.  In that service() I create objects and link them together.

In PHP frameworks we have exactly the same problem: Controllers are
our version of Servlets, which have a constructor not available for
collaborators. I know you do not like frameworks, but in PHP they
provide the functionalities of a Servlet Container, which would be
missing without them.

Creating a single Controller is not viable because it would have to
handle routing and bootstrap by itself (so much for using a
framework). I will think about it, however.
I've seen different solutions:
1. Instantiating a Factory that creates the necessary collaborators
and keep the controller's code so short that it is tested only
end-to-end.
2. Defining setters which are discovered in some framework hook, and
called with the right collaborators.
3. Use a framework like Symfony2, which provides support for injecting
a Container object into each Controller.
You described 1, and maybe 3 which generalizes 1. I feel 2 would be
the cleanest solution, but 1 or 3 have a better ROI and the
side-effects that your application is not tied to the framework for
more than the code in the Controllers. The framework may be subject to
change, unlike the Servlet api.

--
Giorgio Sironi
Piccolo Principe & Web Engineer
http://giorgiosironi.blogspot.com
http://twitter.com/giorgiosironi

Guilherme Silveira

unread,
Jan 9, 2011, 7:54:11 AM1/9/11
to Growing Object-Oriented Software
> I suppose the intent is that the services object instantiates a First,
> Second etc objects, is that right?  But now you can't pass collaborators to
> these new objects.  This is how a servlet engine works, and it's the reason
> why servlets must have a zero-args constructor.  I don't like this!
Yep... then:

> > services.add("/first", new First(d1,d2));
> > services.add("/second", new Second(d2));
> > services.add("/third", new Third(d1));
> > new Server(services).start()

The problem now is that if the lifecycle I wanted to have for fields
within First were request based, now they are App base. An example is
the database connection, which would not allow me to share the
connection between first and second in the same request without using
ThreadLocal?

> Another solution might be to pass factories instead of class objects.  That
> sounds a bit more complicated though.
Yep. The problem that we see is in the end every object having its own
provider/factory/adapter (whatever every framework calls it). It
sounds like 2x code..

> If we are talking about a web application, I really don't like this design.
> I don't want User objects to live beyond a single request.  If I need to
> know stuff about the logged-in user I will load that from session storage at
> every request.
Anything you store in session? Imagine that's the thing you want to
share between two components.

> Disclaimer: this is how *I* do things. YMMV.
Not a problem... trying to find out how the code would look like and,
in the end, if it would really be easy to maintain those lifecycles
and scopes. It seems like the dev can still do nasty things with or
without the frameworks, doing bad things seems as easy as it was when
using them, does not?

Regards

Guilherme

Matteo Vaccari

unread,
Jan 9, 2011, 6:02:51 PM1/9/11
to growing-object-o...@googlegroups.com
On Sun, Jan 9, 2011 at 1:54 PM, Guilherme Silveira <guilherme...@gmail.com> wrote:
> I suppose the intent is that the services object instantiates a First,
> Second etc objects, is that right?  But now you can't pass collaborators to
> these new objects.  This is how a servlet engine works, and it's the reason
> why servlets must have a zero-args constructor.  I don't like this!
Yep... then:

> >   services.add("/first", new First(d1,d2));
> >   services.add("/second", new Second(d2));
> >   services.add("/third", new Third(d1));
> >   new Server(services).start()

The problem now is that if the lifecycle I wanted to have for fields
within First were request based, now they are App base. An example is
the database connection, which would not allow me to share the
connection between first and second in the same request without using
ThreadLocal?


In ruby you could do something like

  services.add("/first") { First.new(d1, d2) }
  services.add("/second") { Second.new(d2) }

I.e., you define a block of code (a closure) that will be executed for every request by the services object.  That frees us from having to define separate factories.
 

> If we are talking about a web application, I really don't like this design.
> I don't want User objects to live beyond a single request.  If I need to
> know stuff about the logged-in user I will load that from session storage at
> every request.
Anything you store in session? Imagine that's the thing you want to
share between two components.

In most business apps, the only thing I really need to store in session is the logged user ID.  I can imagine situations when you are tempted to keep sessions in RAM, but that makes it much more difficult to scale horizontally.  What sort of stuff do you keep in session usually?
 

> Disclaimer: this is how *I* do things. YMMV.
Not a problem... trying to find out how the code would look like and,
in the end, if it would really be easy to maintain those lifecycles
and scopes. It seems like the dev can still do nasty things with or
without the frameworks, doing bad things seems as easy as it was when
using them, does not?

Indeed; I lean heavily on the "no needless frameworks please" side.  It's true that you can learn lots from frameworks, but in general I prefer to invest my time learning to program well rather than learning how to use frameworks well.  I suppose spending time with frameworks is a necessary learning experience.   Perhaps one that we should repeat from time to time.

Matteo 

 

Regards

Guilherme

Mauricio Aniche

unread,
Jan 9, 2011, 8:32:47 PM1/9/11
to growing-object-o...@googlegroups.com
Hi,

Programmers can write bad code with or without a framework. I don't
think that using a DI framework might lead you to poorer design
because it kind of "hides" dependencies from you. In fact, most of bad
design I've seen weren't using a DI framework (so the dependencies
were very clear to those programmers).

Besides the fact that if a programmer wants to write bad code, he
will, I want to discuss the following: I believe that some
dependencies need to be more explicit than others. Suppose that a
class depends on some class that access the database (a DAO). These
kind of dependencies usually never change in runtime. I know that my
class depends upon some Dao interface, but I don't care if a OracleDao
or a MySqlDao is injected.

Now, suppose some class that depends on an algorithm that may be
composed by many other small behaviors. An example that comes to mind
is a price of a service which may be calculated by its tax plus profit
that the company needs plus basic price, etc. All of them implement
PriceAlgorithm interface and I compose the behavior just like that:
priceCalculator = new Tax(new Profit(new Basic(...));

Now suppose some other class that issues invoices and depends on this
algorithm to calculate the final amount plus a DAO:

public class InvoiceGenerator {
public InvoiceGenerator(ServiceDAO services, PriceAlgorithm algorithm) { ... }
public void issue() {
for(Service service : services.all()) { /* use algorithm to
calculate price and issue an invoice */ }
}
}

When creating this InvoiceGenerator, I don't care which implementation
of ServiceDAO was injected, but I do care about the price algorithm
implementation as it would change the expected behavior (if I add or
remove one behavior in that decorator, for example). Did I make my
point and showed a differences between these two dependencies? Does
that make sense?

How do you deal with them? A solution would be, instead of injecting
PriceAlgorithm directly, injecting a PriceAlgorithmBuilder which is
responsible to build this algorithm. Any other ideas?

Regards,
Mauricio

Reply all
Reply to author
Forward
0 new messages