Getting to the Monetary Value of Software Architecture
March 1, 2010 4 Comments
Software Architecture is a huge topic and it’s something I am passionate about. I believe, and can prove, that continuous improvement in this area will contribute to overall better system design, faster bug tracking and fixing, reduced maintenance time, faster development time, developer happiness, quicker time to market, and allowing you to allocate more time to keep up to date on the newest technology – to name just a few things….
Now, translate this into the Bottom Line of the Business….
- Faster ROI for software projects
- Reduced Downtime
- Faster time to market for new features
- Reduced labour costs on software projects where the additional labour can be put towards additional stages of the project or other areas
- Bottom Line -> Reduced Costs, Greater Profits
Let me share a case in point that compliments this theory nicely along with details to indicate the higher monetary value of the well architected solution …..
I’m going to discuss a feature we added to an existing project and how it was implemented using a sound architectural strategy. This is just a small piece, an enhancement really, to an existing system that has been well architected.
We developed a solution to allow users to search and filter a combo box while typing into the text area of the combo. This allowed users to find what they were looking for faster. The before and after scenarios are contrasted below…
User had to know the complete item name in the list of potentially thousands of items and carefully scroll through the list to find the item.
Users only need to know part of the item name that they are looking for and just have to type it into the ComboBox to filter. This is an incredibly quick and easy feature for the user and eliminates time required for them to scroll through the list. As an added feature, a little filter icon is shown in the combo box to denote that the combo box list is only showing items that match the filter criteria.
(Note: Some data has been blurred to keep certain customer information confidential)
As you can see above, the user just types in ‘007’ which is the suffix to the part they were looking for in the list. This enabled them to quickly find what they were looking for; in this case, only one part had that specific suffix. In this case, there are over 240 items in the drop down list that the user would have to navigate through to find what they were looking for if this filter functionality was not in place.
I could have implemented this in many ways, but I decided on an architecture that would allow me to reuse this functionality many times over with little effort. I created a class that encapsulated all of the functionality required for the filter functionality to work. This approach requires no additional filter specific code in the main application. With this new class (about 64 lines of new code), I can create a new instance of it in any project and have instant and seamless filter/search functionality for any Combo Box.
It’s now literally one line of code to add this functionality (essentially 64 lines worth of functionality) to any of our ComboBoxes. You could loosely (very loosely) say that your productivity is increased by 64 times when implementing this filter functionality in any new scenario using this approach. However, read further and I’ll cover a more accurate metric.
I’ll contrast this implementation scenario with another very common scenario:
The developer opens the project and finds the Combo Box he is going to add the filter functionality to and starts coding away by handling the events of the Combo Box, adding code to various places, debugging, and a few hours later he has something that works pretty well. He/she does a bit more testing, fixes some bugs, makes a few changes, and here we have something that seems to be perfected.
The change is rolled into production and the users LOVE it! They can think of how useful it would be to have this functionality on a few more Combo Boxes.
(this is where it all goes wrong)
The developer goes to add this functionality to a few more Combo Boxes. For each combo box the developer is doing the following:
1) Find all the code in another area of the application that has the filter combo box functionality and copy it …. (“Where is all the code I need? Grrr – which pieces of it do I need again?”)
2) Paste it into the code module in another area of the application where the new functionality is needed
3) Look through all of the code and replace control names, key strings, and other variables with the ones we want to use for this instance
4) Test everything to make sure we aren’t missing anything
5) Ooops, something is not working right – maybe I forgot to copy something or change a value somewhere?
6) Ahh found it, I didn’t handle one of the events of the Combo Box properly and this was causing all kinds of problems
7) Copy and paste this piece of it
8) Code has been added in various places to support this new functionality, I need to do some serious integration testing to make sure I didn’t screw something else up
9) Ok, finally, everything is a go – let me post this.
Now the user wants the functionality in a few more places. The developer finds this tedious, but continues to do it this way for each combo box. This is tedious and time consuming and introduces more opportunity for bugs due code integrated into multiple places and tightly coupled within the system; due to time constraints it becomes tougher to introduce this functionality in too many additional areas.
With the well architected solution we get the following direct benefits that we would not see in the above scenario:
- Write once, reuse many times – easily!
- Effort does not need to be repeated for each place we want to use this functionality
- Changes to functionality are made in the Class and bug fixes and enhancements do not need to be manually replicated for as many times as the functionality has been implemented
- Code is refined, tested, and encapsulated from the rest of the project and from the ComboBox itself
- Test Driven Development is supported as the idea is to de-couple the functionality from the system so that it can be reused – this decoupling makes it easy to write automated tests if necessary
- Testing of the main components limits any re-testing required because the code is always the exact same code and not just copied and re-integrated from place to place
How can we put a monetary value on this?
Now, add up the time it took to create, test, and debug the initial filter component and get it working once. This is your Y value.
Now, add up the time it takes to copy the functionality to one more area as per the steps listed above and multiply that by the number of times you need to duplicate the functionality. This is your X value.
Now, come up with a number as to how many places could benefit from this new introduced functionality. This is your N value.
Now, add up the time it takes to add one line of code to a project to enable this filter functionality on an additional Combo Box. This is your Z value.
Cost of a well architected approach to implement: Time = Y + (N x Z)
Non architected solution: Time = Y + (N x X)
This just shows the initial up front cost savings. Take the other benefits into account, as listed above, and you can see a much higher monetary value.
To Add Insult To Injury…..
Now, wouldn’t it be great if we could have the filter search all of the columns for the combo box instead of just the one. We could just add a new option to the class to allow that or enable it by default for all ComboBox’s using the filter. Let’s hope they are all using this architecture – I don’t know a developer who would enjoy going back and modifying (or adding) the code for every combo box so that it can support this extra functionality. Unfortunately, in that scenario you’ll have added unnecessary labour cost to the project to get this additional functionality or the functionality just wouldn’t be added and the feature set of the system would suffer.
In a follow up blog post, I’ll actually discuss the code used and the approach taken with the code for this solution in particular. I will however share, in this blog post, the one line of code required to duplicate this functionality (64 lines of dispersed code, reduced to 1):
Dim partfilter As New UltraComboTypeFilter(ucboPart, “PartNo”)