Tuesday, August 25, 2009

Adventures while building a Silverlight Enterprise application part #20

This post is about some of the less technical (a.k.a functional) stuff around code generation, especially when using XAML, it being in either Silverlight or WPF. This is a no-code post, that is intended to give you some food for thought when planning for code generation on different levels.

The basics
If you're involved in applications that have large amounts of, well, something, it may very well be feasible to use some form of code generation. You could use this for many things and most of them, if not all, have been done already. Some common items in software that may be candidate to code generation are:
  • Business objects
  • Screens / windows / forms in the GUI
  • Reports
  • Database scripts
And obviously there are a lot more. There are only two basic requirements to code generation. What you plan to generate needs to be in some format you can actually supply from some peace of code and what you plan to generate needs to have some form of repetitiveness to it.

The most common thing to generate is your Business objects. They tend to be very repetitive and as they are in some programming language it usually is enough to generate simple text. If you're application is based on some relational database, you might even be able to leverage the metadata in your database as a source for generating your business objects.

Setting goals
The first thing you should do when thinking about code generation is set goals. What I mean by that is you should think about not only what you're going to generate but also why. Is this generated code only a starting point and are you never going to regenerate? Or are you interested in regenerating code at some point? The answers you give on these questions have a big impact on how your generation process should look.

If you're generating only once, you need to make sure that any metadata you use in the generation process is definitive. Experience tells us this is nearly impossible to achieve, so at least make sure the impact of a change is as minimal as possible and also make sure your generated code is readable.

If you are going to regenerate, consider the fact that not only do you need to run the process and make sure you're not loosing any customizations on the generated code, you also need to make sure that any source of metadata is consumed again. More on that later. Another concern when regenerating is integration testing. When you regenerate part of your applications source, you've altered all that source and changes are something is going to fail because of it. Make sure you think about how you're going to at least test for failures, or better yet, prevent failures in the first place.

Have a business case
You may or may not have to pitch code generation in your organization, however you should always have a business case for a code generation process. What I mean by that is you should at least have some clue as to how much effort it will take to build the generation process and how much time it will safe you in the end. Basically you need to have a Return On Investment calculation, at least for yourself, before you go off and invest a lot of time into this. I know it may seem that you won't invest that much at first, but trust me, you'll most likely end up spending at least twice the time you figured before you actually set down and made a decent estimate.

When looking at this business case, make sure you do not only include the obvious. Everyone can figure out that it saves time not having to write a specific amount of code. What is getting left out a lot is the quality of the code that is generated. It's consistent, which means you can test one instance of the code and you'll know the rest will work. This also means it reduces the amount of bugs and if bugs are found in generated code, it reduces the amount of effort to fix these bugs.

Having worked for several software companies in different roles I know from experience that having less bugs is an even bigger win than spending less money on writing code. Having a bug doesn't only cost money, it also impacts reputation and customer satisfaction at some point. Having less bugs is good for everybody.

When things get tricky
You obviously can't generate every bit of code in your application, however most of us will be tempted at some point to try and generate something to hard. One of the most underestimated peaces of code to generate is part of the GUI.
Let's say you're building a Line Of Business application that has one hundred forms in the application that are being used for data entry. This is obviously a very common scenario. Not many developers like to go out and build that many forms. It just feels silly doing repetitive work if your job is all about automating repetitive tasks.

However, there is more then meets the eye here. Let's say you want to do this for a Silverlight application. At first glance, all you need to generate is some XAML for each form and it needs to contain some TextBlocks to contain the labels and some other controls to be used for input. All seems fine so far.
Now consider the metadata you need to actually generate this. You may say that you already have this as it is the same metadata you've used for generating your business objects. Is it? I doubt that. The only thing your business object tells you is what fields it contains and what types they are. They don't tell you anything about their position in a form. There is no information about any special behavior that this one specific control needs different from most others.

All that extra information needs to come from a functional designer, it being some application expert or even one of the developers in the team. Now let´s say you have this metadata in some usable form. You´re still not capable of generating a functional form. Now you need to bind to your business objects. Initially this isn´t that hard, but things start to get complicated when your datamodel evolves or when the functional designer desides to link in that one field from some other business object on the same form, because that is easier for the user.

Now let´s say that you even got that under control. Now you still need to ty in behavior. You need to attach events, which means you also need to generate the code behind for your application, but you also want to be able to extend the code behind at some point. The metadata you need for that process has to come from a developer at some point.

If you now look over the big picture for generating XAML forms, you have not one but three sources of metadata:
  • The datamodel
  • A functional designer
  • A developer
And these three sources of information need to be brought together so they can be used in a single generation process. Building something like this quickly becomes a project on it's own, rather than just a meens to an end.

Putting it in perspective
So shouldn't you do this? That's a good question and there is no simple yes or no answer. It all boils down to your ROI calculation as I explained it earlier. How much effort goes into building and implementing this way of building your GUI in the organization? And how much effort is going away from building and maintianing it in a traditional fashion?
Obviously if you have an increadibelly large application, this might actually work, but another case in which this may work is if you're a one-man-show. If you do the datamodel, the functional design and develop the application, then this might just be worth the effort. The reason for that is because you control all the variables and there is no team to keep in check on how to work with this.

So what if you figure out this is not a good approach for your project, should you just go off and build a hundred forms by hand? Well, not so fast. If you can eliminate one or two of the sources of information, by not generating that part of the code (or at least not in the same component), you may just be able to make it feasible. The thing to keep in mind is that combining metadata sources makes things more complicated, so try and keep them seperated.

I hope this article helps you out with your choices in wether or not to generate specific parts of your application code. If you have any questions, remarks, etc. you know the drill.

No comments:

Post a Comment