views:

208

answers:

5

Our software shop does a big enterprisey system and one of its part is a sophisticated monitoring and log viewer tool. Recently one of our teems rewrote it, since previous version was really lacking some essential features. And it was really ugly.

Since this team is bored with enterprisey stuff and they heard of IoC and Spring ("Seems to be cool, ya?"), they thought it's a good idea to use it in this app. As a result I have around 170 objects configured via Spring (almost every seen in app). Every simple object is connected via tag. Of course everything is a singleton so adding a feature like multiple file processing is almost impossible.

May I assume that using Spring this way is quite "controversial"? I thought IoC and Spring suits other needs (like change of database driver or other dynamic configuration).

EDIT: GUI of this app is a little bit similar to Visual Studio GUI. So I have tab with log file (and this is one Spring component). I have tab for bookmarks (one Spring component). And so one: imagine that for every tab in Visual Studio you have one Spring component. And every component has interface only capable of connecting with other single component.

So it is possible to have to file tabs (configure two compoennts). But that means two bookmarks windows (which makes no sense - in VS you habe one for every file).

@Earwicker: almost every single class in this project is configured via Spring (file loader, file indexer, bookmark tab, file tab, colorizer tab)

+1  A: 

When you say "everything is a singleton" do you mean that that's how it happens to be configured within Spring? I wouldn't expect the types themselves (in code) to be singletons - indeed, part of the point of being able to configure things with IoC is to avoid genuine singletons (which make testing harder, for example).

I can't really guess the best way to implement the "multiple file support" your question talks about without seeing the code - but it certainly shouldn't be too hard. There are various ways you could approach it, either injecting a factory for the appropriate component or letting your application ask Spring to create components when it needs to. (The latter is more invasive in terms of dependencies to Spring, but may mean less boiler-plate code.)

It's very hard to judge code without seeing it, but creating a complex application via a large number of loosely coupled components configured using Spring doesn't sound too bad to me.

Jon Skeet
+1  A: 

Dynamic configuration (like changing a database driver or replacing a layer with a mock one for testing) is only one of the many advantages of Spring and IoC in general. Perhaps the main advantage is the complete separation of concerns. All objects become independent of each other, perform a specific task and it is the responsibility of the container to wire them together.

Also in Spring the singleton concept is somehow different from the design patterns singleton. I would say that using IoC is appropriate for every application of medium or large size. Perhaps the developers weren't very experienced with Spring and didn't use some of the more advanced techniques, which really reduce code size and produce a more elegant result.

kgiannakakis
+2  A: 

From your description (as others have said) it is not possible to judge whether the resulting design is good or bad.

The ultimate extreme of IOC looks like this: every useful API is wrapped in a component class. The parameters to that API are supplied by other components. For example, if the application might need to read a file, you'd have a component (in pseudocode):

public class ReadFile : IStreamFactory
{
    IFilePath _path;

    public ReadFile(IFilePath path)
    {
        _path = path;
    }

    // implementing IStreamFactory
    Stream Get()
    {
        return new FileStream(_path.GetPathString());
    }
}

So now to make that object capable of opening a stream on a file, you need to write another component that implements IFilePath. You could write several: a component that stores a constant filepath (read from configuration, of course!), a component that combines two filepaths, a component that takes plain text from another component (implementing another new interface, ITextSource?) and merely checks that it's a valid path.

You get the idea, anyway. It's almost as if you take every single line of an ordinary application and make that single line into a separate component. Another example:

class IfThenElse : IAction
{
    IBoolean _test;
    IAction _ifTrue;
    IAction _ifFalse;

    // omitting obvious constructor

    // implementing IAction
    void Do()
    {
        if (_test.GetBool())
            _ifTrue.Do();
        else
            _ifFalse.Do();
    }
}

You'll need other components representing a "scope within which variables can be declared", and a "named variable declaration" and a "reference to a variable", which must somehow be able to work on any type of component.

So now you need to tie all these miniscule fragments together in a gigantic XML configuration file, to assemble them all back together into an application.

If you've really done this at the lowest possible level, it will be pretty absurd, because the task of writing the XML file will be comparable to writing an application in the usual way. Except that the syntax will be XML-based, the names of all the functions will be completely non-standard, and the debugging support will suck.

If you can find a "sweet spot" somewhere above this, then your XML format might be something that users will prefer, and find easier to learn, than "raw" programming in the underlying language.

This is very similar to a point I made the other day about XAML.

Daniel Earwicker
A: 

In the experience that I've had on spring, I would tend to go for an architecture that only the beans that you know are singletons should be spring managed. Other beans should rather be managed by code in those spring beans. iow, manually.

That way there is a strong separation between what spring does and what the application does. It becomes tricky to use spring, and it's advantages if you use it for the non singleton objects in your context, as you are now experiencing.

I do acknowledge that this will not hold for every situation, but it sounds like it could be applied in yours.

Michael Wiles
+1  A: 

Spring is there to help not to hinder or restrict you, but to clean up all the boiler plate code no-one wants to see or write as well as testing/db support etc etc.

It's true it technically is possible to swap out a persistence implementation for example, but in reality this rarely happens and it will have an impact on your interfaces no matter how agnostic you think they are.

A better reason here for using Spring is as I have already mentioned; testing...

I don't following your comment regarding everything is a singleton, it if the case this is certainly a decision made by your architect because you can have non-singleton's or prototypes in Spring and are encouraged to do so where needed to avoid anemic domain models and classes which look procedural or scripted.

It is certainly not difficult to work with prototypes objects in Spring.

Remember, under all the glossy exterior and IoC, Spring is simply a Factory.

JamesC