I always try to follow the DRY principle strictly at work; every time I’ve repeated code out of laziness it bites back later when I need to maintain that code in two places.
But often I write small methods (maybe 10 – 15 lines of code) that need to be reused across two projects that can’t reference each other. The method might be something to do with networking / strings / MVVM etc. and is a generally useful method not specific to the project it originally sits in.
The standard way to reuse this code would be to create an independent project for the reusable code and reference that project when you need it. The problem with this is we end up in one of two less-than-ideal scenarios:
- We end up with tens/hundreds of tiny projects – each to house the little classes/methods which we needed to reuse. Is it worth creating a whole new
.DLL
just for a tiny bit of code? - We end up with a single project holding a growing collection of unrelated methods and classes. This approach is what a company I used to work for did; they had a project named
base.common
which had folders for things like I mentioned above: networking, string manipulation, MVVM etc. It was incredibly handy, but referencing it needlessly dragged with it all the irrelevant code you didn’t need.
So my question is:
How does a software team best go about reusing small bits of code between projects?
I’m interested particularly if anyone has worked at a company that has policies in this area, or that has come across this dilemma personally as I have.
note: My use of the words “Project”, “Solution” and “Reference” come from a background in .NET development in Visual Studio. But I’m sure this issue is language and platform independent.
13
If they really are reusable methods / classes, you could write them into a small number of ‘Swiss Army Knife’ libraries. We do this quite often at my company; we call them framework libraries:
Framework.Data
– Utilities for working with database queries.Framework.ESB
– Standard methods for interacting with our enterprise service busFramework.Logging
– Unified loging systemFramework.Services
– Utilities for interacting with web servicesFramework.Strings
– Utilities for advanced string manipulation / fuzzy string searching etc.- …
In all, there are about a dozen or so libraries. You can really distribute the code however you see fit, so you don’t have to end up with hundreds or dump everything into one giant assembly. I find this approach fits because only some of our projects will need Framework.Data
and only a few will ever need Framework.Strings
, so consumers can select only those parts of the framework that are relevant to their particular project.
If they’re really just snippets, and not actual methods / classes that can be easily reused, you could try just distributing them as code snippets into the IDE (e.g. Visual Studio Code Snippets). Teams I’ve worked with in the past had a common snippet library that made it easier for everyone to follow our standard coding practices with internal code as well.
4
I disagree with the accepted answer for many reasons.
In my experience, when I see “miscellaneous” libraries like the accepted answer, they’re an excuse to reinvent the wheel (or not invented here(NIH)) – a far greater sin than violating Dont Repeat Yourself (DRY).
Sometimes violating DRY can be a reasonable compromise, it is better than introducing tight coupling. Reuse is a secondary concern compared to good object oriented design. A bit (I mean small amount, apply the Rule of Three) of duplication is easier to understand than a spaghetti code base.
The approach of numerous general purpose libraries sets a bad example. It leads to a fine granularity of assembly and too many assemblies is bad. I recently reduced an in-house from 24 libraries to 6 libraries. It improved the compile time from several minutes to ~20 seconds. Visual studio is also slower to load and less responsive with more assemblies. Having too many libraries also leads to confusion as to where code should live; prefer fewer, simpler rules.
Why is the stuff in the .Net Framework not good enough? The Framework is pretty big; many times I’ve seen code that re-implements stuff that already exists there. Really make sure that your frameworks are filling gaps in the .Net framework and dont just exist for aesthetic reasons (for example “I don’t like the .Net framework here” or perhaps some premature optimization)
Introducing another layer into your architecture has a significant complexity cost. Why does the layer exist? I’ve seen false reuse, by that I mean that, the code is built on top of an in-house framework. It would have been far more efficient to implement it directly on top of standard libraries.
Using standardized technologies (like the .Net framework and popular 3rd party/open source libraries) have benefits that often outweigh the comparative technological gains of building it yourself. It is easier to find talent that knows these technologies and your existing developers will invest more in learning it.
My recommendations:
- Do not to share this code.
- Create a new library if it has a cohesive purpose do not use the ball of mud design pattern.
- Reuse existing 3rd party libraries where possible.
- Prefer fewer assemblies, with simpler rules as to where code should live.
3
For small bits of code — say a single class with no dependencies — we tend to just copy and paste the code into projects. This sounds like a violation of DRY, and I’ll admit it can be at times. But over the long term it has been much better than having some sort of massive, multi-headed commons project for a few reasons.
First, it is just simpler to have the code handy, especially when building and debugging stuff.
Second, invariably you’ll want to make some little tweak to the common code for that project. If you’ve got a local copy of the source than you can just make the tweak and call it a day. If there is a shared library then you could be taking on tweaking that library and then making sure you don’t break all the other apps or creating a versioning nightmare.
So if it isn’t beefy enough for it’s own namespace we tend to just push it into the appropriate bits on the project and call it a day.
3
The second solution you describe is not that bad. In .NET you also reference an assembly from the GAC even if you just use one single class of it. ‘Dragging irrelevant code’ is not that a problem as you might think. In this case it is vital to at least keep related methods and classes cleanly organized in different namespaces. Additionally good practices for API design should be applied to prevent this solution becoming a mess.
If it comes to very small bits of code, I think following approach is a good supplement to a common project: Allow them to be duplicated in different solutions. Deal with them like best practices: document and communicate them to the team.
1
I’ve only ever worked in “enterprise” environments where this sort of thing has been an issue and each time it’s been the second option that’s been adopted. For the most part it’s worked okay because there hasn’t been any constraint on application footprint.
However, having spent the last week with a start-up who are running their own Nuget server I’m inclined to suggest this as a viable alternative. Of course the issues I expect to emerge will be around discover-ability.
If the projects are suitably granular and the namespaces are sensible then I can see this becoming a popular approach in places.
3
I’ve recently thought about this and what occurred to me was a large library of common methods as has been mentioned thus far, but with a twist. The library project would allow you to configure at compile time which pieces are included kind of like the BusyBox project. With that approach, you can have a kitchen sink style library repo, but only grab the tools you need when compiling.
GitHub has a pretty useful tool for saving code snippets https://gist.github.com/
It stores your snippets as git repositories that you can keep private, or use to share snippets with other people.
0
Depending on the size of the team/project/company this will be rather hard thing to do efficintly, unless it is already built into your environment somehow, and every solution you will find (if you implement it) will cost some money. (It may safe you more, but that you will not be able to measure easily). You’ll have to check whether it’s worth the price. Keep in mind, too, that reusable solutions tend to become abstract and often will fit many situations but without being optimal.
In any case, if you want to do this for the code produced by more than one person, at first you’ll need awareness of everybody and cooperation. This includes developers and managers.
Then you’ll need to make sure you know the scope in which you want to do this. Team? Project? Department? Company? Depending on the answer the kind of code you’ll put into such solutions will vary, as will the granularity with which you tailor the dlls. Once you decided on this someone (preferrably with some enthusiasm for the idea – you?) should sit down and start to put some structure into this.
Just creating such dlls will not be sufficient to do the trick, though. In order to make them useful you’ll need to advertise them (to users and contributors) and maintain them like any other piece of software, which usually means that you need to put someone in charge for them for a long time. You’ll need reliable documentation, as well, which will then need maintenance, too. With some luck and cooperation you may end up with some best practices, but it can as well easily evolve into a project of it’s own, depending on the size and number of teams involved. And for that you’ll still need management support.
i have run into issue a lot, and my prefered solution is to post the code in a github/pubic web-enabled repository. it solves a lot of problems –
- easy access and easy to share. cvs/svn/enterprise-repos mean checking out project into multiple IDE workspaces, and sometimes having to switch workspaces or computers just to refer to a small code snippet.
- assuming these snippets of code are not proprietary/classified pieces of code and are variations of publicly available knowledge, posting them on a public repo like github means others will look at it, and might even contribute.
- posting something in the public domain under your name has the added pressure of reputation. you will double check and update things, since it reflects on your abilities as a programmer.
- updates. the thing about maintaining code snippets in a repo is, if a snippet hasn’t been used in a long time, it might go stale (contain outdated apis/libs). example – java code snippet to read a file. you might have figured out the best way to do this in 2009, but in 2014 a new file api comes out that changes everything. your snippet? still stuck in 2009. in a public repo, things will get updated, either by you (because bullet 3), your teammates, or some member of the general programmer population, and in the process, you might even get suggestions to fix something that you might have been doing wrong for a long time.
One thing i would recommend- no matter where you keep your snippets, always google stuff up before you use it. things change all the time. saved snippets save time, but also breed complacency.
We have a separate project “utilities” where we store all these small methods together with tests.
When a project need some utility it just adds the source file with the required method with “add as link”.
This means that there are no run time dependencies added (unless the included file need one).
The system has worked well but like all others it needs diciplin on what is a utility. Requiering high test coverage has worked well for us and tests are also good usage documentation. Discovery is still an unsolved issue for us.
One complexity with the utility project is to decide visibility level on items. A rule of thumb is that methods should be internal and data structures public.
My company uses intranet-local web services. We have a few web services that are set up as common internal web services, and when another project needs access to one of the services it sends an http request with a defined interface. Since it’s on the intranet, housed in the same server farm, these requests are very fast.
Obviously this only works with internet apps (and only works in millisecond times when on the same local network), but it has some really nice advantages.
I recently came up with this service: Snip2Code (http://www.snip2code.com).
It’s an interesting way to share just your snippets (not entirely libraries) with your team. It breaks the usual point to create common libraries that should be referenced in other projects, and in my opinion this is a valuable vision.
Moreover, there are a lot of scenarios were the use of a common library simply doesn’t apply: let’s consider for example some Design Patterns like Singleton, Strategy or Observer. You can create libraries to support such patterns but still there’s no 100% coverage.
The real need is to have a tool to share common practices among the team. I tried to use Github’s gists but I’m stuck with the search of them (really poor) and with the fact that I cannot share them just among my team and not with other…
(Disclaimer: I’m one of the founder of Snip2Code, and I was – together with my co-founders – in your very same mindset some time ago: this is why we decided to start this project!!)