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.

+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.
–
JDBApr 5 '13 at 19:28

2

@ColeJohnson .NET in itself IS a huge reference! Probably much bigger than the dlls I'd make myself.
–
George PowellApr 6 '13 at 12:02

2

I get that. However, .NET's JIT compiler only loads the required methods into RAM (when they are called)
–
Cole JohnsonApr 6 '13 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.
–
George PowellApr 8 '13 at 10:39

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.

+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...
–
Marjan VenemaMar 30 '13 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.gMar 30 '13 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.gMar 30 '13 at 16:52

4

+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.
–
Steve EversMar 30 '13 at 17:22

2

@SteveEvers I'm actually working right now on setting that up. :P
–
p.s.w.gMar 30 '13 at 17:28

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.

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!
–
glenatronSep 18 '13 at 15:58

1

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.
–
sleskeOct 2 '13 at 12:31

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.

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.
–
Andrew FinnellJun 23 '13 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.
–
Michael DurrantJun 23 '13 at 15:09

2

+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.
–
Eamon NerbonneJun 24 '13 at 21:58

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.

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.
–
pokeMar 31 '13 at 4:40

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.

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.

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.
–
pdrMar 30 '13 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)
–
ofraskiMar 30 '13 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.
–
pdrMar 30 '13 at 18:24

@sarfeast It would be nice if you could share a link to whatever Nuget server is, and tell a little about it.
–
hstoerrApr 2 '13 at 11:02

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.

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