Code Renaissance is about building great teams and great software. By exploring best practices, team interactions, design, testing and related skills Code Renaissance strives to help you create the team and codebase that you've always wanted.

Oct 29, 2011

Named Function Expressions in JQuery & Knockout JS

Recently I was working with JQuery & Knockout in javascript and got a long running script error so I broke out the profiler to see what was wrong. Unfortunately both JQuery and Knockout code take in a lot of anonymous functions so looking at the profiler and the stack wasn't especially useful. To make the debugger and profiler more more useful I added a name to the function expression that I suspected was causing the problem similar to this:

//Changed form this:
viewModel.FooBar = ko.dependentObservable({
  read: function(){ //Note the anonymous function expression
     return this.foo() && this.bar();
  },
  owner: viewModel
});

//To this:
viewModel.FooBar = ko.dependentObservable({
  read: function readFooBar (){ //Note the name readFooBar 
     return this.foo() && this.bar();
  },
  owner: viewModel
});

These are called named function expressions (NFE's) and they can be seen in both the profiler and the call stack. As it turns out the function that I was troubleshooting didn't have a problem after all. Later the same trick allowed me to verify the real problem was in a custom binding that I had written.

Using named function expressions hasn't been common up till now because there were issues in IE8 and lower, however these issues are easily avoided by 1)giving all named function expressions unique names withing their enclosing scope and 2)NEVER referencing the NFE name in your code (IE9 and other major browsers don't allow you to do this anyway). By following these rules and making this small investment in your code you can earn huge dividends when debugging and profiling.

Jul 18, 2011

The Lie of Reusablity

The lie of reusability in software engineering is that modules and controls that are competently designed  are easily reused and that reuse will translate into increase productivity. Business people love this concept, which has ample examples in the physical world, because reuse should save time and time is money. So they push the expectation of reuse and increased productivity on developers who strive in vain to bring the myth to life. In practice though, reuse usually requires significant effort and the main benefit you get, at least the first couple of times something is reused, isn't increased productivity, it's increased maintainability.

Consider a simple textbox control (win-forms, asp.net, etc). It took thousands of hours of effort (adding together the planning, coding, testing and maintenance time spent on the control) to bring that level of reuse to your finger tips. It seems like a simple control, but it has lots of events and properties that make it work for everyone and behind those are a myriad of subtle and well thought out decisions that have perfected it for general reuse.

Anyone who has ever tried to do simple composite user controls for internal use can tell you that even that relatively minor level of complexity has can contain a host of hidden and unexpected problems. Ever purchase a user control from an outside vendor? Worked great didn't it... until you got past the basic cookie cutter code and tried to get it to work in you particular context with your constraints; under those conditions subtle little problems emerge and it often falls just short of what you want it to do. Now go hunt down one of those developers and ask how much blood, sweat and tears their team put into getting that control to that level of reuse.

The truth is when you build a module or control you have no way of knowing how or even if it will be reused. The best you can hope for is to follow best practices and to keep the code as clean and well commented as possible... anything else is wasted time. When you reuse it for the first time you now have a new context to code for and the code will have to be adjusted to work in that context and then refactored mercilessly to make the code clean again. In all likely hood the this work will take longer that the initial work on that item. In the next iteration if you're lucky you may get your first efficiency gain from reuse but adjustments will still need to be made.

One real danger in iteratively adjusting code for reuse is increased complexity. Each iteration will likely have new features and requirements that will have to be added to make it work in that context. The larger the code becomes the harder it will be to understand the code as a whole and the more work it will take to change it cleanly.

In some contexts ("okay now we need all but one of the fields to be read only and we also need 12 additional fields and one button added, but only here") it may be worthwhile to simply build a new control or module to handle that particular case. Yes there may be some code duplication, which you may or may not be able to refactor it our into a common module, but everything in software is a trade off. You'll have to ask yourself which hurts you more (makes things less maintainable), the code duplication or the loss of cohesion and added complexity?

Of course if you're a developer who's been around a while you've likely already been through all this, perhaps wondering what you're doing wrong that the dream of reusability isn't working for you. The truth is you're likely not doing anything wrong... reuse can be a worthwhile endeavor but in all but trivial cases it's going to be difficult.

Jul 11, 2011

Quotes for Software Developers #3: Efficientcy

"There is nothing so useless as doing efficiently
that which should not be done at all." [Peter Drucker]

My Take On It

Unneeded, poorly planned and underutilized features are one of the biggest wastes of time in software development. You can run the most efficient team in the world but if you're allocating time to unnecessary fluff, you're wasting time.
Is that feature needed? Really? If it is, is there a better way to do it? The longer a bad idea lives the more time it wastes. If it makes it into production not only was the development time wasted but maintenance time will continue to be allocated to a feature that never should have been.

Implement the minimum set of features first and build upon them incrementally. Kill feature ideas early and often. Good ideas will come back again and again until they're implemented.