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