In enterprise IT organizations with multiple development teams, code produced by one team is potentially useful to others. Such code could be, for example, a parser for common XML documents, a service for converting image files on the fly, or utility methods for validating key business data. (Note that I'm using the term "code" loosely to mean any sort of artifact produced by a development team, including libraries, executables, and live services.) In the interest of reducing development time and costs, enterprise architects may seek to establish a code reuse policy.
But simply declaring that "all teams should reuse code whenever possible" is not going to accomplish much. There are likely cultural barriers to remove and new incentive structures to establish to make code reuse both possible and advantageous to development teams.
To determine what specific changes are necessary in your enterprise, consider the following good excuses for not reusing enterprise code.
- I didn't know that code existed. Autonomous project teams may not collaborate often or at all with other teams, resulting in an ignorance of what code exists within the enterprise and what other teams are currently working on. Perhaps the enterprise does not provide a central SCM with read access for all developers. Or if it does, perhaps the process for a developer to request read access is so onerous that most don't bother. It could be that nature of the SCM system itself is inhibiting developers from looking at other teams' code (ClearCase, anyone?).
- I don't know what that code does. From my experience, enterprise code products tend to be named after the project that births them, and projects tend to be named with some indecipherable acronym or random, non-descriptive word ("Turtle", "Omega"). Even if everyone in the enterprise knows about the TOBIT project, if its codebase lacks helpful README files or web accessible information that enables other developers to quickly understand the purpose/use of the code, consider reusability a non-starter. Don't expect developers to read through 100+ page Word documents or find information in a repository geared towards project management, either.
- I don't know how to use that code. Developers that manage to discover enterprise code, understand its purpose, and realize its reuse potential also need guidance on how to use that code. Documentation and sample code checked into source control alongside the codebase is beneficial. In the absence of documentation, the ability for developers to be able to speak with the code's authors is important, so make sure there are no policies inhibiting such discussions from happening. In organizations relying on contractors, there may be rules disallowing someone working on contract A to talk to someone on contract B without pre-approval.
- That code is not packaged in a reusable manner. Before any serious policy on reuse can be enforced, your organization must establish its own centralized artifact repository and ensure build pipelines are publishing code produced by enterprise development teams into that repository. Furthermore, projects should be packaging their products in a reusable manner. For instance, Java code packaged inside a single, monolithic
.warfile is not readily reusable (outside of copy/pasting). If the application were broken down into multiple, cohesive modules packaged as
jarfiles, however, other teams could reuse them by declaring dependencies in their POMs.
- That code is not cohesive. Project teams tend to produce a single deliverable with a context bounded to the project's entire scope. For larger projects, such a context involves so many concerns that the deliverable is only useful for that particular project. Consider an image converter service that converts, does OCR, updates an RDBMS with captured text metadata, and sends out email alerts when the text contains certain words--all in a single transaction. This service lacks cohesion; another project needing just the image conversion capability would not be able to reuse this service. Getting project teams to produce artifacts with more specific, cohesive contexts may require changes to development processes to allow and encourage these results. Alternatively, project formulation processes could be adjusted to establish smaller, more focused project teams.
- That code is highly coupled. I recently added a single enterprise library into my own project's POM. In the process of doing so, Maven downloaded a slew of transitive dependencies including (I kid you not) an older version of Spring, HSQLDB, mybatis and Hibernate, Jersey, Cobetura, JavaMail, Apache Commons CLI, the Amazon AWS SDK, Ant, and BeanShell (RIP). This library is far too coupled. Generally speaking, any library which imposes on you the need to adopt (or tediously exclude) many other libraries is not built for reuse. Another example of overly-coupled "code" is an image conversion web service that takes an ID as input, where the ID is path reference to an image file housed in a filesystem mounted to the server. The conversion capability is coupled to a filesystem. A more reusable conversion web service would allow the input image to be streamed over HTTP.
- That code lacks sufficient test coverage or has quality issues. Confidence in code libraries can stem largely from their popularity. I have no qualms adding Apache Commons Lang to my project, primarily because it's used in a lot of other projects. Internal source enterprise components do not have such wide usage, though, so one has to base confidence on other factors, such as the quality of the code, the maturity of the development practices of the organization producing the library, or the team's commitments to quality. If your enterprise does not make code quality information transparent, or tends to produce code with poor quality, development teams may not be confident enough in other teams' code to want to reuse it.
- That code is not designed to support our additional usage. This excuse relates to "code" in the form of live services. Even if a project team has managed to build a useful service, project budget/time constraints may have prevented it from being architected to scale beyond that project's immediate needs or to support more rigorous SLAs. Or perhaps code is architected to scale but the project's budget is too limited to accommodate additional expense from extra-project usage. It may not even be lack of money; billing processes may not allow more than one project to be invoiced, effectively restricting use of certain resources to one particular project.
- That code's project team cannot support our reuse efforts. "Support" can take many shapes, from being available to answer questions to responding to bug reports to actively releasing new versions. A project team could view it as a risk to have to spend time addressing bugs discovered by another project, especially when the bug does not impact their own project, so they may refuse to provide any SLA or to take responsibility for bug fixes. In cases where another project team is willing to contribute bug fixes, perhaps the SCM restricts them from easily doing so. Establishing clear ownership, responsibilities, and SLAs are important for encouraging reuse. Having an SCM that supports contributions from outside the team is beneficial, as well.
- That code is not being actively maintained. On the other side of the coin, developers may be dissuaded from reusing some code if no team is currently maintaining it. Project managers could view the adoption of the code as a project risk given there is no one to reach out to for support and any newly discovered issues with the code would have to be addressed by the project team itself; it's the "you break, you buy" mentality.
Enterprise architects should assess which of these excuses apply to their enterprise and experiment with implementing measures that would render these excuses illegitimate. Each organization is different, so there could be other good excuses standing in the way of a successful code reuse policy.
Finally, do some cost calculations to determine if pursuing code reuse will actually provide a return on investment. As Jessica Kerr concluded in a May 2016 blog post, "avoid shared code libraries, unless you're Google and have perfect test coverage everywhere, or you're Amazon and have whole teams supporting those libraries with backwards compatibility." Unless your enterprise is willing to pay for perfect test coverage and dedicated support teams, it might be cheaper to continue the "not invented here" status quo.