Fog Creek Software
Discussion Board




Question on code maintainability

I'm wondering about a hypothetical situation, where I have a jsp web application, and I'm wondering whether any JoS readers have any input.

My hypothetical webapp is a struts application running on tomcat, and the architecture is thus:

1st layer -  Code that gives me an 'object model' of the database, so I can create a new object, use its mutators, and save it, and this does the appropriate insert.

2nd layer - Peers that enable me to select, insert, update and delete the relational equivalents of these objects from the database

3rd layer - API that has many classes with static methods that operate on the second and first layers.  For instance, a caching API for drop-down menus (that is updated when data in the database is updated), various other API's for manipulating the data in ways I won't go into here

4th layer - Struts actions and actionforms

5th layer - JSP's

Now I'm fairly clear on the usefulness of my 1st and 2nd layers.  What I'm curious about is the third layer, and wonder whether if I was creating a system such as this, I'd be giving myself maintainability nightmares.  The third layer would often use various services to be found elsewhere in the third layer to give the results to the fourth - for instance many functions would update caches.

I've wondered wheth it would be better to set up a listening interface so that bits of the api could register themselves with the events they are interested in, as this feels like a more 'correct' approach.  The approach I've described makes me feel slightly uneasy, and I'm not sure why, as I've done stuff before like this and it has worked fine.

Has anybody got any experience to bear on this?  Any gotchas?

Pondering
Thursday, August 14, 2003

Consider this off-beat perspective:

Your layers encapsulate the system view of the application. They certainly make it easy to switch persistence models, or rip out the web UI and replace it with a GUI.

And if that's a *real* requirement, great.

But is that the most important perspective to considr? maybe you need to organize your encapsulation/modelling around the entities that represent the user's perspective.

If you're curious, here's a link to a chapter in the Naked Objects book that makes the point effectively:

http://www.nakedobjects.org/section4.html

Read the next few pages, especially their critique of Component-based software development and the MVC pattern.

--
http://www.braithwaite-lee.com/

Reginald Braithwaite-Lee
Thursday, August 14, 2003

Thanks for your comment.

That's an interesting answer Reginald, partly because what this system would do is present an interface to the user in a similar way to the 'naked objects' approach.  I'm not winding you up.  This would be meant to generically handle data whatever needs to hit it, so the problem domain is pretty wide.

So my problems would be along the lines of enhancing the user interface so it had more functionality around data, and adding more features so that data can be manipulated, so I want it to be extensible as possible - partly because I'm not so smart and I can't foresee what people will want from it.  I want to make sure I'm not heading towards a big ball of mud further down the line.  Does my question make more sense knowing that, or do you think I'm concentrating on the wrong things in your opinion?

Pondering
Thursday, August 14, 2003

Your third layer sounds like it could be rife with dependencies and tight coupling.

Also, 'static' is often a euphemism for 'global' in Java.

-Thomas

Thomas
Thursday, August 14, 2003

I agree, the third layer is where problems would occur.  And you are right that 'Static' is a euphemism for global.

My theory would be that I'd be exposing services for the layer above (that could be used by any of the struts actions).  Say with my caching class, used by many of the third layer 'static' methods, how do I untangle such a thing?  Do I stop them being static and get each of the actions to create an object through which they can use the API?  I'm still not sure how this would solve the problem but I'd love any suggestions.  Do I create a kind of 'internal task'-based API that isn't static?  How do you get around this?

Pondering
Thursday, August 14, 2003

Use the static methods only for the creation of singletons and factory-made objects. Then have those objects provide the services.

T. Norman
Thursday, August 14, 2003

That's a damn good idea - thank you T. Norman.  As far as I see, the works for the whole lot.  I'm a bit fuzzy about the benefits of using a factory for those services that need to be accessed by various different struts actions though - what benefits would that give me over just using 'new'?  Been trying to puzzle this out.  I love learning more about this.

Now in the case of a cache as singleton, that still needs to be centrally accessed so I guess I do need some kind of static route into the one object - what benefits would this give me over just making it static?  In effect it's hiding behind something static that will give a reference to it.  It feels a more controlled and refined way of doing things, but I'm wondering what effects these subtleties will have...

Pondering
Friday, August 15, 2003

Ah another question, sorry about this - if I want to have classes register to be notified with certain events, like I could be registered to be notified if a row was added, how would this be accomplished unless I was using singletons?

I've been trying to think it out in my head without success.

Thanks for the help

Pondering
Friday, August 15, 2003

"what benefits would that give me over just using 'new'?"

Outside of factory methods or singleton creators, avoid using 'new' for classes that you want to be extendible and modifable in the future.

If you do something like

  Foo bar = Foo.createFoo();

you can seamlessly alter or enhance the functionality by deciding at runtime to return an instance of a subclass of Foo based on certain conditions.  You could easily return a BigFoo, SmallFoo, or IPityTheFoo with little or no code changes.

But using 'new' would marry you to the specific class Foo. Which may not be a problem if you only use 'new' in one place, but once you provide a public constructor and ten other programmers start using 'new' also, you're stuck.

Similarly, singletons enable you to take advantage of inheritance and polymorphism because static methods are not polymorphic.  And because a singleton is an object, it can easily be passed to something that registers objects as being interested in receiving events or messages.

T. Norman
Friday, August 15, 2003

*  Recent Topics

*  Fog Creek Home