I am not a fan of software methodologies, third party libraries, hyper-generalized frameworks or other so called productivity enhancers within the software development process. At the same time, I abhor the idea of a thousand developers at a thousand keyboards creating a thousand screens, features, pages and trying somehow to stitch them together into a cohesive software product.
What do I like? Small teams of smart developers who understand how to build small re-usable frameworks to solve problems that they have already solved, and are likely to need solving over and over. Guys and Gals who are likely to re-factor their initial solution into a mini-framework. Sometimes these frameworks “adhere” to each other, and grow into something more comprehensive. Other times they are simple labor saving through code re-use.
Productivity enhancement through labor saving may be a goal (original goal) of methodologies, libraries and frameworks, but often along the way, they take on a life of their own. Sometimes they actually get in the way. I have watched (this week) developers struggle with frameworks and libraries that we adopted because they were supposed to help – but instead of delivering working software capabilities, we get partially working capabilities and everyone is bitching about the default behavior of this that or the other. The developers want to use a different third party library – they think it is better documented and better behaved.
A couple times, I heard developers say, “That is not the default behavior of the < insert brand here > widget.” To which I responded, ” Really, I didn’t know our customer required the default behavior.” I think that you all can imagine the “Come to Jesus” meeting that followed that exchange.
As software engineers, we are expected to:
- understand the functional requirements
- infer a reasonable set of technical requirements and have the customer validate those,
- propose a technology paradigm appropriate to meet the need
- implement a solution against that paradigm that meets both technical and functional requirements
Software engineers are expected to deliver solutions – like when the vended library default behavior doesn’t meet the customer requirements it requires a solution. Software engineers are expected to build engines – or frameworks if you prefer – that give the development team “leverage” to deliver working software capabilities efficiently (not the thousand developer solution).
The original term engineer was a military term for those who designed, constructed and built warfare engines: bombs, catapults, battering rams, etc. These engines were built to knock down walls, castles, strongholds of the enemy. Without these engines, military leaders (Kings and Generals) would only be able to apply manpower – brute force to defeat their enemy. These engines multiplied the effectiveness of their troops, and allowed them to be victorious with fewer men and fewer casualties.
Software engines or frameworks are not different. They can amplify the effectiveness of our team, and can allow us to do more work with less overtime, less pain, less hassle. When I think of software engineers, I don’t think of the engineering disciplines that we have today, but the engineering disciplines of martial combat that spawned the term engineer in the first place.