Something I have noticed in many conversations, whether on twitter or in real life, is that we never have enough context. When people describe all the challenges they face writing code, it’s hard to grasp the culture various developers experience. And culture is key. But another overlooked aspect is exactly who is the customer for your code. That’s because writing framework code is different than end user apps.
What is framework code?
To make this comparison, we must answer the question: what is framework code? What’s different about it and what’s the same?
Framework code, when done right, helps people write end user apps. The more apps people can write, the better the framework. A framework that helps you write one app but not the next isn’t much of a framework at all. In other words, frameworks must handle some common problems that people run into. They must simplify things for the developer and actually handle a problem they would have to handle themselves. Over and over. Otherwise, developers aren’t interested.
The most widely used, yet smallest, framework code I can think of is leftpad. This itty bitty library reached epic visibility when the developer pulled it from npm. The impact against all the toolkits and frameworks was incredible, filling the Internet for days (including an opinion from yours truly). In essence, people use frameworks to solve a problem so they can shift focus and work on what their end users really need.
Frameworks are about solving generic problems. To be widely adopted, it must be very effective. One of the most effective aspects of a framework is being able to upgrade without breaking your end user app. This is one of Spring’s strongest anchorings. Use Spring, don’t get burned by upgrades. Use Spring, simplify coding Java apps.
To carry out this backward compatibility, the Spring team takes on several responsibilities.
- We don’t break APIs on minor or patch releases.
- We only add to APIs on minor or major releases.
- As a corollary, we don’t bump up the minimum required version of Java except during a major release.
These standards have made it MUCH easier over the years for people to upgrade and inherit new benefits. To carry out these standards, we have to be VERY careful when making changes to the framework. And being such a community oriented framework, we often have to carry out detailed conversations with users and contributors to ensure these standards are upheld.
Often, this requires saying “no“ to certain contributions. Even to certain ideas. When a framework takes on too much, it can become wholly unmanageable. It’s better to say no, and let end users consider adding their special case than taking on something few will use. In fact, frameworks that make it easy to extend are highly welcomed by communities for this very reason. If you won’t do it, perhaps I can?
What is end user code?
End user code is very different. This is code aimed at solving a particular user’s problem. Usually, this is directly tied to invested dollars. In other words, clients hire software teams to build certain things. And they expect to be rewarded for their investment with operational apps.
The requirements gathering process isn’t perfect, but the ability to put together a list is much more concrete than framework developers, who are merely anticipating developer needs. Or trying to look at lots of different users in the community, and coming up with a general solution. How does this difference manifest?
It’s a lot easier to throw in a partially implemented feature to an end user app, put it into production, try it out, and then remove it later. Indeed, this process is much smoother with an end user app than it is for a framework. We refer to this as agility.
Frameworks can do this type of experimental research as well. But the dynamics are very different if you put out a poorly designed feature. What if your half baked idea suddenly becomes the community’s favorite feature? Your option is to:
A) Live with it and maintain it.
B) Yank it, and cause breakage.
C) Change it, and cause breakage.
If you have established a high level of quality, avoiding breakage can push you into a very costly maintenance cycle. If you are waiting for the next major release to remove it, and that isn’t coming for another two years, you have been coached on why you don’t want to just “throw something out there” for a framework with a strong community.
When people argue on Twitter about the impact of breaking code, this entire dynamic between framework code and end user apps seems to go missing. Different teams are driven by different requirements. It pays to understand how writing framework code is different than end user apps. So what do you think? Is there really a big difference between framework code and end user apps?