Reusable Code: The Good, the Bad, and the Ugly
We preach reusability and sometimes strive for it, but it rarely becomes a reality.
Join the DZone community and get the full member experience.Join For Free
The mythical "reusable code" idea has existed for decades. It showed up shortly after the first lines of code were written. We preach reusability and sometimes strive for it, but it rarely becomes a reality. I've seen various levels of success with this over the years. Everything from "we have a reusable library that 75 percent of us use" to "we have shared code libraries here, but never use them in your projects."
A recent discussion led me to think about this: Why don't more software development organizations have shared code libraries? Is it the pointy-haired bosses preventing it? Team conflicts? Or is it the developers themselves?
You may also like: Code Reuse Is Not a Good First Class Goal
We can't blame the pointy-haired bosses for this one. If you explain the basic concepts of reusable code to management, most would agree it's a great idea. Building something once, so you don't have to build it repeatedly? Easy to find the upside here.
Team conflicts can also contribute to it, which is usually people disagreeing about who gets to determine what code is shared. Developers themselves can also be opposed to it, due to not having enough time to build them.
All of these are contributing factors to lack of adoption, but the question you should ask is do we need reusable code libraries at all?
What Are Shared Libraries and Why Do We Care?
If you have tasks your developers are building that contain code you can use for something else, you put that code in its own "library" to use later. This can be a DLL, a folder of snippets, a Node module, whatever. Connecting to a database? There's no reason to write that code for every piece of software that accesses a database. Create a DB_Connect class, and put that in a file you can copy to another project later.
It's easy. You take a function and if it's abstract enough, parameterize it and make it available for other projects to use. When you start your project, you don't have to write code to connect to the database; pull the library and enter your parameters. Here are some upsides:
- You write code once and use it multiple times (saving cycle times)
- If tested thoroughly, it cuts regression errors
- It enforces standards other groups can follow
These are all great reasons to use shared libraries. Countless articles and books have been written about code reuse, and most of you are familiar with them. The biggest selling point for this is not having to code "boring stuff" over and over and have wild variations of the same methods in the wild. This frees up time to work on exciting features.
How Are They Used?
Here are some ways shared libraries are used in business:
- Internal Use: Code that is shared with internal groups and used for projects
- External Use: Code that is designed for programmers outside the organization to use
- Forked: Users can take your initial code and "fork" it to make it work for their specific needs
This falls in line with the DRY principle of software development: Don't repeat yourself.
Do We Want Shared Code Libraries?
Why isn't everyone doing this? Your organization may avoid shared libraries for a good reason. Not every project or team benefits from this, and it's not the magic bullet to solve all development problems. Here are some reasons not to use code libraries.
- Distributed Monolith Problem: If you put something into a library and everyone uses it, that doesn't mean it isn't bad. An inefficient database connector design means everyone is using an inefficient database connector. Changes to your implementation can still have negative cascading effects. A small change to an API could mean every single system is now broken.
- Dependency Hell: If every piece of software is relying on your library, there's a tight coupling in place. There will be a myriad of dependencies in place, for instance, relying on a framework like Angular. If you have software built to use a specific version, upgrading it could produce a chain reaction amongst your applications.
- Inflexible Design: Sometimes you're asked to use a design in a certain way that's different from what you actually need. Because "everyone else is doing it," you're forced to make your code work around it, which can then increase development time. Wait, why did we build shared libraries in the first place?
- Programming Language Lock-In: Too many times I've heard "well our library is written in ____ so you have to use that," which means you're locked into a single programming language. This can lead to using the wrong tool for the job. So, don't assume because your team doesn't use shared libraries means they're unenlightened and don't want better production.
What to Examine if You Want to Use Reusable Code Libraries
If you're considering creating reusable code libraries, you should first see if it makes sense to do so.
- Take a hard look at the design: Then look at it again. Will you really benefit from it? Do you have repeated code now? Are there any issues that may encourage tight coupling?
- Closely examine your dependencies: Are you creating dependencies others will have to work around? How often do they change? Can they bypass the ones you create?
- Start as abstract as possible: You want your libraries to be highly abstract so that they perform expected functions, but can be overridden or extended to meet specialized use cases. Give them the basics but let them evolve it how they'd like.
How to Get Developers to Implement Them
So, you've decided you want a shared library. Here are some ways you can help teams adopt your library:
- Steal it from an existing project: This is the easiest way to start a new library. Take an existing project and remove everything that's specialized and keep everything that can be re-used and feels solid.
- Thoroughly test it: The last thing you want to do is introduce problems into the software. After building your abstract library, test it thoroughly so you can rely on it, and help developers find regressions. Don't hand them garbage and expect them to use it.
- Examine all current use cases: By digging in and understanding how people will use your library, you can determine whether it will benefit them, and whether to make changes. Do this on a method by method basis to ensure that you're asking them to use something that will work for them with minimum effort. Like most anything in business, success will come from great communication. Top down design is not your friend here, you'll want to examine the needs of the group and design a library from those needs.
Most of the organizations I've been involved with do not use a shared code library. They're usually in some form of working towards one, and only two where they were implemented and working well.
At one end of the spectrum, you have a pattern where all repeated code is in a library. On the other, you'll have no code library, and everyone builds software for their own projects. You'll find success somewhere between the two. How far you lean toward each extreme will depend on your needs.
There are abstract functions that should always be shared. Some that come to mind are authentication/authorization, database connections, and logging. It should be either a shared library you developed, or one that's open sourced and built by someone else. Everything else should be examined, considering the overall design.
Don't jump to conclusions and take on a large project to build a giant code library that will make developers lives worse. But don't exclude the idea altogether. Be purposeful and observant to find which strategy will work best for your projects.
Published at DZone with permission of Jeremy Morgan, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.