IMO, the best reason to use DI is to simplify testing. Is the current
backend code easy to test and maintain? Would using DI make it easier?
Would it make easier for developers to understand Roller's codebase?

I'm definitely +1 for moving to a DI architecture because I think I'd
understand it better. Guice is used internally by Struts 2
(via XWork), but I'd also encourage you to look at Spring 2.1 since
it added many of Guice's features. Craig Walls has a couple of blog
posts about it:

http://jroller.com/page/habuma

Matt

On 5/19/07, Allen Gilliland <[EMAIL PROTECTED]> wrote:


Dave wrote:
> I started playing with Guice and found it very easy to understand and
> use. I've looked at Sping IOC a number of times, but I've never been
> able to figure it out. Guice is different -- it's easy enough for a
> dummy like me to understand. I started working on a Guice version of
> Roller and had the basics working in only a couple of hours.
>
> I'm not proposing that we start using Guice (yet), but I would like to
> explore the idea. So please take a look at the changes in the
> branches/roller_guice branch, which are described below, and let me
> know what you think.

After a quick look through the code I am generally unsure how using DI
here is the right decision, but I think we need to improve the way the
backend code is initialized anyways so at least this is progress.  I am
definitely a fan of using DI where it make sense, but I don't think that
DI applies in all situations and I'm not yet convinced that the Roller
backend should really use DI.

In specific, based on the way our code operates, I think it is most
appropriate that any instance of the Roller interface should be treated
as immutable.  Our code does not in any way support (or need to support)
modifying an instance of Roller after it has been constructed, so for
proper api practices we should be forcing instances of the Roller object
to be immutable.  It is for this reason that I think that DI for the
Roller backend is not appropriate.

This doesn't mean we can't use Guice or some other framework to help
with wiring up the backend, it just means that we should be structuring
our code to properly enforce a solid api.  The one big change that I
would make different from what you currently have is that instead of
providing public setXXXManager() methods which can be injected, instead
those manager instances should be passed into the constructor or
whatever is responsible for building the instance.  This way we still
use Guice to wire up the backend and we enforce immutability which is
appropriate for our api.

One other thing that I think we should take more seriously in our
backend code is how we enforce the singleton pattern.  Currently we do
not enforce that pattern in a proper way and it's always kind of bugged
me.  To truly enforce the singleton pattern we should only provide
private constructors and the single instance of the class should be
created statically and returned via a public static method.  Since the
code is supposed to enforce the singleton pattern on all backend
instances I think we should be properly following this pattern, but most
importantly this should be the case for the Roller object.

So, just to be clear, I am not trying to shoot down the idea of using
Guice or any other framework for object wiring, like Spring, but what I
don't want to see us to is make a bad api choice just so that we can use
some of the convenience these frameworks provide.

-- Allen


>
>
> *** Guice Dependency Inject (DI) in Roller, an experiment
>
> ** Goals
>
> - Get started using DI in Roller so we can simplify Roller bootstrapping
> - Don't change the public "Roller API" i.e. RollerFactory and Roller stay
> - Maintain same level of back-end pluggability via
roller-custom.properties
>
> ** Status of the branches/roller_guice
>
> - Roller backend can now starts-up via Guice
> - Still need to eliminate RollerFactory from backend
> - Still would like to create Manager interface to standardize manager
> lifecycle
>
> ** Advantages
>
> - All the well known advantages of DI
> - Easy to define alternative backend modules for testing
> - Gives us a way to get rid of the various factories around around
> - Less code in RollerFactory
>
> ** Implementation notes
>
> - RollerFactory
> The factory is now resposible for instantiating the Guice module
> specified in
> roller.properties like so:
>
>
guice.backend.module=org.apache.roller.business.hibernate.HibernateModule
>
>   And here's the new RollerFactory: http://tinyurl.com/ypmeeg
>
> - HibernateModule
> A backend module is responsible for binding interface classnames (e.g.
> Roller)
> to interface implementations (e.g. HibernateRollerImpl). The Hibernate
> module:
>
>   http://tinyurl.com/2bffkt
>
> - RollerImpl
> The Roller implementation doesn't create managers anymore, all managers
are
> injected by Guice. It's a Guice @Singleton. Here's the new RollerImpl:
>
>   http://tinyurl.com/ynu2me
>
> - HibernateRollerImpl
> The HibernateRollerImpl no longer creates managers either, instead it
> relies
> on the fact that it's parent class RollerImpl is injected.
>
>   http://tinyurl.com/yrb4rm
>
> - HibernatePersistenceStrategy
> The HibernatePersistenceStrategy takes care of it's own initialization
> using
> RollerConfig (someday with a DatabaseProvider). It's a Guice @Singleton
> too.
>
> - Managers:
> The managers all use constructor injection now. The Hibernate managers
> expect
> to get their strategy and Roller instance (if required) via injection. I
> kept
> RollerFactory in the "public API" so there is zero impact on front-end
> code,
> but all references to RollerFactory should be eliminated in the back-end
> (that's work still to be done).
>
> - Added Roller.init() method due to circular dependencies
> Some managers need access to a Roller object as part of their
> implemenation,
> so I've added a Roller.init() method. I'd like create a Manager
> interface as
> we have in Planet to standardize manager lifecycle.
>
> ** Notes on Guice
>
> - Simple small API that is very easy to understand
> - Documentation is short and to the point
> - Error messages are very good
> - No horrible XML files to write



--
http://raibledesigns.com

Reply via email to