Kiss My App

Wednesday, September 22, 2004

Java or .Net

I'm writing this entry while reading a book titled "C# for Java Developers".

Java is cool, but I'm tired of having to learn 5 different ways of doing one thing. Not only playing a guessing game of possible solutions, but once picking a solution, books tell you to wrap the solution up in a facade, adding more complexity to your application.

That's not to say that patterns are patterns, in any language, but with .Net you are left with the confidence of a strong single leader, Microsoft. Sun and Java, on the other hand, is led by commitee. Smart people are tossing API's out there left and right that are nothing more than ideas-- J2EE for example. Again, I'm left with picking a vendor/solution for every "idea" they throw out there.

With Microsoft, things are pretty much set in stone via the tools they provide. This is how .Net handles MVC, this is how .Net handles Database access, this is how .Net cooks a turkey.

I would feel more confident know that our implementation was written on a single standard versus constantly wondering if we made the right pick of persistent frameworks a month after finishing a project.

Monday, September 13, 2004

Refactoring With 'Chain of Responsibility'

I've been thinking a lot lately about all of the complex business logic we have to handle at the company I work at. Sadly, we do the best we can in OO terms, much of the logic is dispersed and replicated across different applications.

Recently one of our older purchasing applications need some changes to the logic of starting an order in our system. At the same time, another developer was preparing requirements for allowing a 3rd party system to start an order over the same application. What was two page long method with logic for starting an order, now would have to bear the requirements of two different systems, our own and a 3rd party system.

While working with the monster of logic in this single method, I was thinking how horrible it's going to be to bolt in the 3rd party requirements. The developer working on the 3rd party requirements would have to probably: modify the current method, or choose the favorite practice of others-- cut'n'paste into a new method to handle 3rd party stuff. Both are ugly and don't help maintainability at all.

My solution was to refactor the method to use the chain of responsibility pattern. Basically, the request to start an order is passed through a series of rules until we can start an order. For our internal start order logic, a start order context is created and passed through steps A, B, C, D. For the 3rd party system, the start order context would be passed through E, B, C, F, D. Notice B, C, and D are reused and can be maintained in one spot for both flows.

You may be thinking that those shared steps could have just been represented as methods and coordinated by two different parent methods (one for internal logic, and one for 3rd party). This may work in many cases, but in our case, a rule may fire off a view to the user (such as selecting a ship to address for an order). When a rule would fire a user to a view, that rule would return a flag signaling the chain coordinator that a rule finished the processing for that request. Example, selecting a ship to would then fire the user back into the chain of rules from the start until the whole chain would finish and kick them out of the flow (being able to actually add line items).

It was a simple refactoring. I didn't attack it with hopes of creating a workflow system or anything, just a few simple classes and a couple interfaces. If the logic ever changes or needs to be modified, we can just add another rule to the chain.

Friday, September 03, 2004

Test Driven Development

I last ranted on MVC frameworks on how they tie your business in. I also mentioned a little bit about unit testing. Developers talk about Test Driven development. What does that mean? Does that mean that I'm constantly running tests on everything I write? No, not really. Test Driven development is where the test environment drives your code/model.

Let me explain with a simple use case of logging a user in. The use case is conceptually simple, it's all in how you implement it. Some might dive into an MVC framework or start writing their Actions and JNDI or EJB dependencies and you will find yourself in a very complex situation very fast.

With Test Driven development, you are basically working in a 'main' method, which makes it difficult to commit or create dependencies on external technologies-- this is what we are trying to fight. By removing your ability to create external dependencies within a unit testing environment, the code you develop becomes much more portable.

Lets say we need to communicate to the Database for logging a user in. Some may commit to a persistence framework to take care of the dirty work, but the initial overhead on committing to something like Hibernate doesn't make your objects independently testable. You start getting into the practice of facades and delegates with seperate implementations/responsibilities.

I could get into code examples, but you get the idea. Just search the internet and you will find lots of examples of XP/Test Driven practices that are worth taking a second look at now that the hype has cleared.

MVC Frameworks

After playing with multiple MVC frameworks, I've come to a reoccuring conclusion that they are crap. If I want to use Struts, I have to write Actions and ActionForms, if I want to use WebWork, I have to write Actions, if I want to use Spring's I have to write the same types of objects. JSF is kind of what I'm looking for. Basically, MVC frameworks shouldn't require me to write code to adapt to their framework, the framework should use the code I already have.

With JSF, I use EL-like markup in configs to modify the state of my objects and call behavior on my objects. If I were to use one of the other frameworks, I would have to script, in Java, the behavior or state changes to fit inside of their MVC framework. This increases the complexity of my application, decreases reusability, and decreases testability. I laughed to myself when I read in the struts-dev forum about people trying to expose Struts Actions as web services. Nice, I hope your company has an excellent pre-nup with the technology you married.

Some of the issues with controllers you can run into are:
  1. Changes in session variables, such as the account you are working with
  2. Caching of scoped data
  3. Testability
  4. Reusability
The holy grail of controllers? Beans. Beans have state and they have behavior. I can 'new' myself a bean in a JUnit test and I can instantiate it from any MVC framework out there. JSF promotes this kind of controller behavior through getters/setters and action methods. Behavior and state is encapsulated in units of work. Set the account id on a bean, then ask for all of the products you've ordered. Simple, plug that bean into any framework you can come up with.

One of the other points I brought up was handling state changes. Lets say I have an 'Order' bean in the user's session. I also have a global 'Application' bean that contains the current Account the user is ordering with. Being the state of the web, I could be working with the 'Order' and the Account could magically change on you. How do you suddenly respond to that when you are working with an 'Order'? Simple, PropertyChangeListeners. Refresh your state on the next request when the Account changes, no "cache the data in the session, retrieve and check the account it was good for", you will know if/when the account was changed during the lifecycle of your beans.

In summary, pull your logic out of the MVC framework you're using. Put it in a POJO bean that implements Serializable and progress with confidence through testability and reusability.

Thursday, September 02, 2004

The State of Presentation Design

Web applications are broken up into layers-- one of which is the presentation layer. Developers at heart, are lazy folks and would like to have a presentation layer that works for all types of clients.

I've been reading about advances in CSS. Dan Cederholm has an awesome book out called "Web Standards Solutions" in which he describes how to simplify your HTML markup and through CSS. You can have one page serve browsers, printers, and handhelds. Imagine structuring a web page of pure XHTML markup, then telling your boss that, "Oh, by the way, the application also works on handhelds and all the reports are printable in a pretty format."

Start taking a closer look at CSS to accomodate presentation versatility. No more digging though JSP pages with layout tables within layout tables within tags just to display some data. CSS is an EXTERNAL way of displaying your data without the layout fat embeded in your presentation logic. Here's a list I've composed on the benefits of CSS on your next web project:
  1. Layout code is externalized which makes each page much smaller to download
  2. Smaller pages are easier to maintain when mixed with JSP tags
  3. Pages can be reused for screen, print, and handhelds
  4. CSS behavior is now very similar across different browsers
  5. Creates seperation between HTML structure and presentation (layers are good)

As always, HTML layouts are trial and error with getting things to act perfectly across all browsers. It's almost a blessing that Internet Explorer has more security leaks than-- (Windows?) because with each release, the W3C CSS compliance level increases to a level equal to Mozilla, the other white meat.