115

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:

  1. 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?
  2. 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
  • 23
    +1, although I think there is an element of humor in someone working with .NET being concerned about dragging in irrelevant code via a DLL reference.
    – JDB
    Apr 5, 2013 at 19:28
  • 2
    @ColeJohnson .NET in itself IS a huge reference! Probably much bigger than the dlls I'd make myself. Apr 6, 2013 at 12:02
  • 2
    I get that. However, .NET's JIT compiler only loads the required methods into RAM (when they are called)
    – Cole Tobin
    Apr 6, 2013 at 20:07
  • 1
    True. Although you still have to distribute the whole .NET framework to anyone who wants to use your product, and big projects and complex solutions are more difficult to manage. Apr 8, 2013 at 10:39
  • 2
    Related: When is a 'core' library a bad idea?
    – Alex Angas
    Jun 25, 2013 at 7:45

12 Answers 12

78

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 bus
  • Framework.Logging - Unified loging system
  • Framework.Services - Utilities for interacting with web services
  • Framework.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
  • 4
    +1 This would be my approach as well. Interested to know how you decided where to put code that deals with stuff from two or more aspects. For example IPAddressToString. And whether you allow these libraries to use each other. For example services and data can probably benefit a lot from logging... Mar 30, 2013 at 16:38
  • 5
    @MarjanVenema For cross-cutting code, it depends on what consumers will be find the method more useful. For IPAddressToString, it's likely that consumers dealing with network protocols will have to use that, but consumers which do a lot of fiddling with strings may not really care about IP addresses at all. That would probably end up in a networking package rather than Framework.Strings.
    – p.s.w.g
    Mar 30, 2013 at 16:50
  • @MarjanVenema We try to avoid inter-dependencies. Our services and data frameworks are written in such a way that they do not do any logging by themselves, but make it easier for the consumer to write proper logging code. Framework libraries are allowed to reference each other, but only by extension - e.g. Framework.Logging.Gibraltar is a particular add-on to the logging system.
    – p.s.w.g
    Mar 30, 2013 at 16:52
  • 5
    +1 You could take these framework libraries and deploy them to an internal NuGet repository (as simple as a network folder) and you've got a nice way to manage it. Mar 30, 2013 at 17:22
22

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
  • 1
    A fringe benefit to using Open Source libraries where available- if you come up with some improvements you can share them back to the community! For example with .Net MS published an EnterpriseLibrary ( now Open Source ) which gives a pretty good set of tools for common scenarios, find something there that can be improved and hey presto! Everyone benefits!
    – glenatron
    Sep 18, 2013 at 15:58
  • 3
    I don't really see a disagreement with the accepted answer here :-). "fewer assemblies, with simpler rules as to where code should live" is not a contradiction to the accepted answer. The answer also advocates only using as many different assemblies as seems reasonable.
    – sleske
    Oct 2, 2013 at 12:31
  • A lot of libraries are made for catering for every type of situation in every type of project for every type of architecture. This means you write a lot of boilerplate code in all your projects everywhere, because the original library writers had to take every possible situation into account. It is way better to wrap the case that you use 99% of the time. I.e. because almost all your database models have a primary key called Id, that the used library doesn't know about. It also saves a lot of time swapping libraries in the future.
    – Dirk Boer
    Jan 24 at 18:53
12

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
  • 5
    I don't agree with this approach. I appreciate the maintenance problems with managing small pieces of code but I would argue that some common library could be created out of all of them like @p.s.w. is suggesting. Having duplicate copies of code with minor tweaks in it is asking for trouble. Assumptions will be made, bug fixes will be missed. Jun 23, 2013 at 13:05
  • 2
    -1 (to the answer). It is certainly easier to have everyone have their own copies of their own versions of programs. This is how software was developed in the 80's. I have since learned that - long term - this leads to a mess. It's harder to do the right thing and have a common library as people will then have to communicate much more about their work. Well, they should. Jun 23, 2013 at 15:09
  • 5
    +1 - I think it's worth mentioning this approach even if it's not one you want to use very often. Some snippets are more like design patterns - you'll reuse em, but slightly differently everywhere, and perhaps in different languages, and perhaps you'll want to change them. Also, a broadly reused library is inflexible in that changes to its API are very risky. Finally, having this approach as a fallback increases the quality of shared libraries by keeping experimental stuff out of them a little longer. Jun 24, 2013 at 21:58
6

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
  • 1
    Except that for non-standard libraries, this means that you'll have to ship a large assembly just because of a single (or few) uses. This is not an issue for standard stuff as that's available anyway, but I'd definitely avoid shipping large but mostly unused assemblies if you can split it up in a good way.
    – poke
    Mar 31, 2013 at 4:40
6

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
  • In what sense do you expect them not to be discoverable? We use a large, and growing, number of nuget packages in that way. The biggest issue we have is with managing versioning and dependencies.
    – pdr
    Mar 30, 2013 at 16:09
  • Ah, yes. Those too. By issues around discover-ability I mean that given a sufficient number of little packages with specific function maybe it becomes more difficult to catalogue (and find) each. For example, how does your team make known which packages contain various functions? (showing nuget search ignorance here)
    – Kofi Sarfo
    Mar 30, 2013 at 18:16
  • Oh, I see. Yeah, you can definitely put whatever you like in the description and that becomes searchable, but I think we've grouped the packages well enough that it doesn't seem to be a problem.
    – pdr
    Mar 30, 2013 at 18:24
6

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.

5

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
4

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.

4

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 -

  1. 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.
  2. 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.
  3. 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.
  4. 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.

2

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.

2

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.

0

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!!)

Not the answer you're looking for? Browse other questions tagged or ask your own question.