Imperva has decided to gradually shift to a company-wide Platform mindset in which, instead of having a set of separate products and features, there is a set of capabilities and building blocks upon which the products and features are built.
Until now, special Platform teams have developed Platform components.
Now, however, all teams will develop the Platform.
This will have a positive effect on both our time-to-market and our customers’ unified experience across Imperva’s products.
To achieve this, we need to practise even more code sharing within the company than ever before.
Everybody likes to talk about code sharing and how marvelous it is, but there are real issues with it which we need to put on the table and discuss.
In this blog, I’ll talk about the main issues raised by developers around writing and reusing shared code and how to mitigate them.
We’ll also look at real-life examples of how the outcome of code sharing is worth the investment.
Finally, I’ll explain what’s required from an organization to achieve a Platform mindset.
Issues with code sharing
There are many good arguments for why code sharing might pose problems.
Let’s look into a few of these arguments.
1. Why should I write a generic component before knowing if someone else will actually use it in the future?
This is one of the most common questions when talking about code sharing. Writing generic code that fits more than one specific use case requires a bigger investment. Experience and skill are required, both for identifying which functionality in your feature can be shared and for implementing it. Well-defined APIs and documentation are essential, too.
Being API-first and having detailed documentation is a best practice that will benefit you before it benefits those who reuse your generic component.
Even if it only serves your product, you’d like your component to be decoupled from others and written in a way that’s easy to follow and expand – which is exactly what you need for it to be generic.
I’ve been coding for a long time now, and a few years ago I didn’t write generic code like I do today. But, it is now part of my programmer DNA so to speak, and it can become part of the company’s DNA too.
It’s a decision and a process.
If you’ve identified that the functionality you’re writing can be generic, but the conditions for making it so aren’t present and you’ve decided against it, my suggestion – as a last resort – is to put it in a separate package. Try to make it as decoupled from the rest of the code as possible, and make this known at least to the people around you.
While the company is going through the change, even this has value.
2. We are on a tight timeline and have to deliver to the customers. Taking existing generic code and expanding it to fit my new use case will take me much longer than writing new code.
You might be right in some cases, but in many others that’s not the case.
When developers estimate the time it would take them to develop a feature they usually leave out the testing, bugs and enhancements that follow until the feature reaches its maturity.
These things cost more resources.
But, as existing code has already passed these stages, reusing it will leverage its maturity . It may also take less time than you think, particularly after you’ve done this a few times and gained experience.
For example, we had a case last year where a new feature needed a functionality already found in another feature.
It was a service for taking data objects, writing them to files in CSV format and then uploading them to an AWS S3 bucket.
Sounds generic, right?
Indeed most of the code was generic but, to actually use it in another feature, we had to decouple it from the rest of the code, extract it to a shared library, and add APIs and documentation.
At the time, with the usual time constraints and due to the fact that the feature was experimental, we wrote new code for the new feature.
A few months later, another similar use case came up.
Notice the pattern?
If someone needs the same functionality for a second time, there’ll probably be a third and a fourth.
At this point it was clear that this functionality was on-demand in the company and we’d have to share it.
This took a few days’ work.
Integrating with the shared library took approximately one hour.
And, other aspects aside, we saved weeks of development.
3. Expanding existing code to fit my new use case can cause a degradation to existing features.
If you’re using this argument, it could mean that your testing coverage is insufficient and needs improvement.
Testing coverage is an essential part of any modern software project.
So again, you’d prefer your code maintenance was less difficult and time-consuming, regardless of whether your code is generic.
Another good solution is versioning of shared libraries.
When you change something, you advance the version of the library and use the new version in your feature.
Everyone else using this library can stay with the old version, and it’s up to them to decide when to move to the new version.
They still need to have good testing coverage to make sure nothing breaks with the new version, but what you solve here is preventing changes from being pushed to other features without their knowledge or control.
4. If we use this shared library that was developed by another team, it will create dependencies between the teams.
Who’s to guarantee that we’ll get their support if we have bugs or feature requests?
True, if there is no alignment between the teams’ roadmaps and priorities, feature requests and bug fixes won’t be handled – or at least, won’t be handled on time.
The company has to define how the Platform mindset will work and solve the “code ownership problem”.
There are good solutions and best practices out there, such as InnerSource, for example.
You need to have a discussion and decide what best suits your company’s culture and technological stack.
Once you do this, what used to be dependencies and viewed as a negative thing, becomes collaboration.
Generally speaking, many companies are talking about the need to increase cross-team collaboration.
And, for me, it’s much more fun to work like this.
A few months ago, reuse of a task distributor shared library resulted in collaboration between two teams that otherwise would hardly have known each other’s names.
And it didn’t end there, collaboration on other subjects continues to this day.
5. How do I know if someone else in the company has already written this code? Do I start asking around?
Another thing a company going through this shift needs to have in place is a location and a process for publishing shared libraries.
It could also be helpful to have a “coming soon” section to keep things exciting and to prevent duplicate work.
What’s required to achieve a Platform mindset?
I’ll summarize what I’ve already talked about and add a few more tips:
- Discuss the “code ownership problem” – present a clear solution that suits your company’s culture and technological stack
- Start small and show a few success stories very quickly
- Set clear goals for the process
- Define a process for publishing shared libraries
- Recruit a few key developers around the company to this cause
- Encourage discussion about shared code; ask to put the issues on the table
- Require APIs and documentation from day one
- Aim for full testing coverage
- Don’t demand perfection at the first stage (or any stage for that matter)
- People often refrain from sharing code, guides, documentation, etc. because they think they have to be perfect before they can be shared with others
- Documentation has to be there, but it doesn’t have to be state-of-the-art from day one
- Well-defined APIs have to be there, but they don’t have to solve a wider problem from day one
- Give special attention to junior developers
- They often believe that making their mark means writing their own code rather than reusing someone else’s
- By receiving guidance and support, their mindset will start to shift
- Finally, talk about it a lot. I’ve noticed that when managers started to persistently talk about and push towards shared code, many ideas of what we could share suddenly arose