Earlier this week I had a long talk with Silvain, the software architects / lead developer on one of our agile projects – being executed using the Smart methodology (see links below). Silvain is concerned about the quality of the software architecture in his agile project. His project is implementing a large number (over 50) work processes and associated forms for a large international customer using Sharepoint technology.
“I’m a bit worried about the software architecture,” Silvain explained me, “because we are implementing our forms and smart use cases one by one. Now we are making a number of architectural decisions for the forms we’re currently realizing, but these decisions might not be optimal to forms that we have to do later in the project.” Off course this is right. An additional issue is that at this point in time we do not have exact knowledge on the processes and forms that will be implemented during the rest of the project. We don’t even know how many forms there are. “But”, Silvain continues, “if I could investigate similar forms that we are going to build in the future, I could make better decisions on the current ones, and avoid possible rework that we would need to do later on in the project on form that we’ve already finished.”
Again Silvain is right. Ultimately, the best software architecture for a project is constructed at the end of the project, when all requirements, both functional and non-functional are known to the team. Unfortunately, this strategy has no use, since your project is already done. In agile development your software architectures evolves as your learn more about the project. This indeed means that decisions made earlier in a project might not be the best alternative, and that you will find more optimal solutions later on. In worst case scenario’s this might imply refactoring of your previouly finished use cases. The big question you will need to answer is this:
Do I need to spend time more time to refactor my code, whenever the final solution for a specific architectural issue comes along, or do I need to spend more time researching all the requirements for this final solution in future use cases?
In my opinion refactoring is worthwhile in most cases. Building software generically to meet future requirements is generally money thrown down the drain. Why? Well, it’s all about making assumptions. The less you know about the future requirements, the more assumptions you are going to need to make to implement your generic architectural solution. And in Silvain’s case we are very unaware of what comes our way in the next six months or so. And the more assumptions you make, the less your solution will meet the requirements when the future is here. In reality it’s very hard to predict the details of functionality that is six months down the road.
So the best advice I could give Silvain is to let the software architecture evolve during the project. My pattern for this is straightforward:
- Take the Nike approach. The first time you are building a specific type of functionality – say selecting from a list in Sharepoint, you take the Nike approach: just do it.
- Copy-and-paste. The second time you scratch your head, but just make a copy of the previous version, and go along with that, as you never know if this type of functionality will hit you again.
- Three is a crowd. When you have an encounter of the third kind, it’s time to shuffle. Look at the previous two implementations, find and implement the pattern in a small framework, and refactoring the previous two implementations. Set out your guideline on your project wiki, or any other central place for saving standards and guidelines.