I am php programmer, but since its not only for PHP, I post it here, it should be good I guess.

Now I want to ask - is there sometimes excuse for dublicating code?

We have this problem:

we make the software, PHP, so push it to the server and its running.

We go and develop other modules of it, which have similar code, so the code could use same functions to avoid dublication.

But - I was told to make it as isolated - try to touch existing code as minimally as posible. WHy? Because - what if in the production bugs start to appear?

Lets say I have modified the code - not dublicating - and I have to delay what I am doing now and go back to bug fixing of earlier code which is in production. But now - how can I do this if I have modified it already? Maybe there is a small fix to that bug, but since I modified it for my new module, it becomes a big fix, so the code would work with new module and at the same time fix the existing bug. The system needs to be carefully tested and worse - it cannot be fixed so fast.

If my new module is isolated from from existing modules, then I can fix the existing module, push it to the production togetther with incomplete new module and it should be fine, since new module is not visible to end user yet. So quick fix can be done without making more bugs. This makes sence.

But I asked my friend, also I have googled about this topic and I only see answer - do not dublicate code.

So how can you explain - how would I solve my situation which I decscribed - to fix small bug quickly, without need to test all modules, but only one to let system run as soon as posible when programming withouth code dublication?

Recommended Answers

All 4 Replies

is there sometimes excuse for dublicating code?

Yes. There's an excuse for breaking any best practice guideline.

So how can you explain - how would I solve my situation which I decscribed

I'm not sure I see the wisdom of fixing a pervasive bug in only one place. Now you have two different versions of the same solution and one of them is buggy! That's called code rot, and it should be avoided, for good reason.

So then I cannot understand why a programmer who has about 6-8 years of experience, has read many books is telling me to dublicate code? When I ask him, he says something like I wrote - to have seperate modules so by modyfying one - we would not break all.

There are a few different issues at play here. The basic guideline of "don't duplicate code" is mostly a consequence (or corollary) of the fact that more code equals more opportunities for bugs. And even purely copy-pasted code is still subject to that problem, especially if you factor in a (past or future) history of bug fixing (fix a bug in one place, forget to do it in the duplicate, etc.). That's a good rule to have on a day-to-day basis in reducing redundant code. That's really the core of the argument against code duplication, and it is a good argument, any experienced programmer will tell you that for sure.

Now, nothing is black and white. And here comes the issue of maintenance of production code and interfaces. First of all, the preventive measures to solve all those problems you described are simple and widely used in production code. They start by a precise and carefully designed specifications for the behaviour of the functions that make up your code (or library of functions), in other words, an API specification (possibly only internal to the company). Generally speaking, when the expected behaviours of the functions (including all erroneous or exceptional cases) are well specified, then that is all you need to fullfill by their implementation, and any bug-fixing to the code that doesn't make a difference in the specified observable behaviour is OK. Then, you need unit-tests and qualification tests that verify that the correct behaviour is observed when running these tests that rely solely on the specified behaviours (i.e., no undefined behaviour). When you do that rigorously, bug-fixing in "live" code is rarely a problem (beyond the logistics problem of distributing the patches, e.g., having your users install the update(s)).

But, your specific problem seems more about wanting to reuse code in a different module / for a new purpose beyond the original intent of it. At this point, interface specifications are very critical because they determine where you can go with this. If you can extend the functionalities provided by a function or module without affecting, in any way, the previously specified functionalities (including expected run-times), then there is really no reason not to simply extend the function with this new capabilities. If, however, what you would need is to reshape the interface (or its specified behaviour) in a way that would serve both the old and new purposes, then you probably shouldn't unless you can clearly show that the old way was much worse (or fundamentally flawed). In either cases, you need to maintain both interfaces, the old and the new, and it is usually easier to put the new, reshaped interface on top of the old one. But, it can also be done the other way around, i.e., you migrate the existing code into its newer incarnation and provide a old-style wrapper to maintain compatibility. The latter is a bit more dangerous, and it is not something you do lightly. And in all cases, unit-tests and qualification tests are critical in making sure that all the correct behaviour is maintained throughout the changes.

At this point, I haven't talked about duplicating code anywhere yet, so I will now. There is only a grain of truth in what your friend was saying. However, the point that "have separate modules so that by modifying one, you don't break all" is incorrect for the most part because it assumes (1) that modifying a module will break it and (2) that it is better to have one faulty duplicated module amongst a bunch of unmodified (or unbroken) modules. To the first point, as I said before, with well specified module interfaces and a fairly rigorous unit-testing policy, the chances of completely breaking a module by some careless modifications are much much smaller (it still happens, of course, but that's why you only modify existing production code after careful consideration). To the second point, well, it just encourages code rot as deceptikon pointed out. And if there is a bug introduced by the change, I prefer that the bug explodes all over the place and be super obvious, than to have to bug only appear in the new module and then have to look for it in all the new code (and the duplicated-and-modified part of it is probably the last place I'll look). If anything, you want your bugs to be loud and clear, and wide-spread, such that you can catch them prior to deployment. Not to mention that having many duplicates of essentially the same code with a few variations is a maintenance nightmare to avoid as much as possible.

The grain of truth in your friend's assessment is that minimizing inter-dependencies between modules is generally a very good idea. It makes for cleaner, leaner, faster, and more modular code. If, once in a while, this means duplicating some trivial pieces of code here and there just to avoid tieing a module with another, just for a few odd ends that are common between them, then it can be totally acceptable to duplicate the code. For example, I have a geometric library that can compute lots of minimum-distance between different kinds of geometry, and then, I have a multi-body dynamics library where one of the elements of it requires some basic plane-line calculations that I could have grabbed from the geometric library, but I didn't because these bits of trivial code (maybe 100 lines of code, total) aren't worth creating an inter-dependency between the libraries in question. But, in cases where the inter-dependency is already there or will have to be there because they naturally fit together, then there is no reason to duplicate the code.

For my part, that summed up the issue pretty well.

Wow, big post, thanks, but some parts sounded bit complicated to understand :)

The grain of truth in your friend's assessment is that minimizing inter-dependencies between modules is generally a very good idea. It makes for cleaner, leaner, faster, and more modular code. If, once in a while, this means duplicating some trivial pieces of code here and there just to avoid tieing a module with another, just for a few odd ends that are common between them, then it can be totally acceptable to duplicate the code.

Then its matter to decide if its ok or not still. Hmm, maybe he used this excude, but I still don't get. Ok but anyway. I guess I should need to show the source first for you to tell if its good or not to dublicate, but I cannot do it of course since its commercial :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.