82

One of the most basic and widely accepted principles of software development is DRY (don't repeat yourself). It is also clear that most software projects require some kind of management.

Now what are the tasks that are easy to manage (estimate, schedule, control)? Right, repetitive tasks, exactly the tasks that should be avoided according to DRY.

So from a project management perspective, it is great to solve a task by copying some existing code 100 times and make some minor adaptations to each copy, as required. At all times, you know exactly how much work you have done and how much is left. All managers will love you.

If instead, you apply the DRY principle and try to find an abstraction that more or less eliminates the duplicate code, things are different. Usually there are many possibilities, you have to make decisions, do research, be creative. You might come up with a better solution in shorter time, but you might also fail. Most of the time, you cannot really say how much work is left. You are a project manager's worst nightmare.

Of course I am exaggerating, but there is obviously a dilemma. My questions are: What are criteria to decide if a developer is overdoing DRY? How can we find a good compromise? Or is there a way to completely overcome this dilemma, not just by finding a compromise?

Note: This question is based on the same idea as my previous one, Amount of routine work in software development and its effect on estimation, but I think it makes my point clearer, so sorry for repeating myself :).

Frank Puffer
  • 6,411
  • 5
  • 21
  • 38
  • 98
    Let us know how your project management chops are feeling when it comes time to hunt down, change and test something in all 100 of those copy-and-pasted instances. And don't forget the additional time that's going to be spent figuring out why it ends up broken because only 98 of them actually got changed. – Blrfl Aug 16 '16 at 12:36
  • 16
    @Blrfl on the other hand, prematurely DRY-ing up code before a good abstraction is clear can really hurt productivity too, as a shared abstraction is a shared dependency. I'm not disagreeing, btw, just pointing out there's definitely a balance to be found. – GoatInTheMachine Aug 16 '16 at 13:07
  • 16
    The principle which prevents DRY from going out of control is the [YAGNI (You ain't gonna need it)](https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it) principle. – Philipp Aug 16 '16 at 13:15
  • 90
    There is no dilemma. If the project manager wants you to do a lot of superfluous manual work because it is easy to estimate, then the obvious solution is to fire the project manager. – JacquesB Aug 16 '16 at 13:22
  • 6
    DRY is to help in future maintenance. That's not something that typically makes it too high on a greenfield PMs priorities. – Matthew Whited Aug 16 '16 at 13:30
  • 1
    @GoatInTheMachine: Sure, and where the balance should be is something you determine using the judgment skills that come from experience developing software. What I read into OP's question is that he thinks the problem is solvable entirely with project management. That's why you don't want a project manager who doesn't understand the project he's managing. – Blrfl Aug 16 '16 at 13:52
  • @JacquesB: That's not my point. The PM does not explicitly demand this. He doesn't even have to know about it. Still it makes his work easier. – Frank Puffer Aug 16 '16 at 19:37
  • 10
    If you do repeat yourself, then ***you still have to do all that other hard-to-estimate work***, plus some extra pointless work. So how does that help the project? – user253751 Aug 17 '16 at 11:22
  • 6
    It's not the job description of a project manager (or anyone else) to have his work easier - it's making a great product. Sure, you want the work to be as easy as possible - but no easier. A project manager that tries to just make "his work easier" is completely useless, especially if you use the MS approach where the manager is there to allow everyone else to work well, rather than being a nuissance :) In any case, your premise is wrong too - repeated code is *not* easier to estimate. Its cost becomes very unpredictable as soon as you need to change anything. – Luaan Aug 17 '16 at 12:42
  • 2
    "So from a project management perspective, it is great to solve a task by copying some existing code 100 times and make some minor adaptations to each copy, as required." Only from a very short-sighted (or sleazy) perspective. You might deliver faster that way, but the maintenance cost/TCO of those 100 copies is at least 100 times greater than following DRY. – Kevin Krumwiede Aug 17 '16 at 19:27
  • 1
    @KevinKrumwiede: To manage a project, the PM needs information about its state. And for this, it is great that "At all times, you know exactly how much work you have done and how much is left.". Everyone knows that copy/paste programming is evil. But it makes managing the project easier. – Frank Puffer Aug 17 '16 at 19:36
  • 4
    Making the management easier at the expense of maintainability is still just [robbing Peter to pay Paul](http://www.phrases.org.uk/meanings/rob-peter-to-pay-paul.html). – Blrfl Aug 17 '16 at 23:22
  • 2
    @FrankPuffer Project management isn't supposed to be easy. Making good time estimates with the aid of an issue tracker is a learned skill. Copy/paste programming is a cheap, dirty shortcut that ends up costing the company dearly after the wanna-be project manager has moved on. – Kevin Krumwiede Aug 18 '16 at 07:25
  • 2
    Typical management, ignoring design time. We would have, ideally, designed out the repetitiveness prior to coding. Instead, management thinks development is a single Olympic event - coding - when it is in fact a decathlon. And they measure to 1/1000 of a second because they think it's all linear. – radarbob Aug 18 '16 at 12:33
  • Something that I think has been missed is that the time to *DoRY* is a reasonable upper bound for the time spent *DRY*ing. If it is truly that difficult to find a candidate that can be reused, then don't. – GalacticCowboy Aug 18 '16 at 17:10
  • 4
    TL;DR: Guy is frustrated he can't predict the future easily, accurately and precisely. Fixes problem by forcing employees to create time-bombs in the codebase. – JS. Aug 18 '16 at 21:33
  • Comments are not for extended discussion; this conversation has been [moved to chat](http://chat.stackexchange.com/rooms/44178/discussion-on-question-by-frank-puffer-is-dry-the-enemy-of-software-project-mana). – maple_shaft Aug 19 '16 at 02:57

11 Answers11

134

You seem to assume the primary objective of project management is to produce exact estimates. This is not the case. The primary objective of project management is the same as for developers: To deliver value for the product owner.

A product using a lot of slow manual processes rather than automation might in theory be easier to estimate (although I doubt it), but it does not provide value-for-money to the customer, so it is simply bad project management. There is no dilemma.

It is well known that estimation of software projects is hard, and numerous books have been written and various processes have been developed to manage it.

If the only objective of the PM was to produce exact estimates, then it would be easy. Just pad the estimates to 10X, and let the developers play games for the rest if they finish early. This would actually be better than your suggestion to use copy-paste busywork to pad the time, since playing games will not reduce the maintainability of the product.

But in reality, the product owner want useful estimates and a quality product delivered as quickly and cheaply as possible. These are the actual constraints a PM will have to navigate.

In any case, I dispute your assumption that repetitive manual work is more predictable than automated. All experience shows that repetitive manual work is more prone to errors. And what if a bug is discovered in the copy-pasted code? Suddenly the cost of fixing a bug is multiplied with the amount of repetition, which makes the uncertainty explode.

JacquesB
  • 57,310
  • 21
  • 127
  • 176
  • 21
    I completely agree with your assertions here but I think it needs to be noted that there are a lot of lousy project managers out there that really do prefer predictability over speed or quality. Most people who have no training in project management learn what they know about it from what they have seen and my experience is that the project managers that can deal with uncertainty in a calm rational way are few and far between. – JimmyJames Aug 16 '16 at 13:46
  • I agree about the primary objective. But in order to do any mangement at all, information is required. Typically the developer provides answers for the following questions to the project manager: How long will it take? What's the percentage completed? When will it be completed? In my roll as a developer I do find it annoying but on the other hand I understand that this information will help the manager. – Frank Puffer Aug 16 '16 at 14:16
  • 5
    @FrankPuffer I've been there. _How long will it take?_ One option here is to provide a range. Read up on [PERT](https://en.wikipedia.org/wiki/PERT) specifically on 3-point estimates because they should know about that already. _Percentage complete?_ This is the most annoying. Try to ignore it but if you can't remember that it's percentage time, not percent of lines coded or whatever. What they really want to know is _When will it be completed?_ Early on, give conservative predictions on each task and refine as you go. Waiting until the last minute to say you more time will make people crazy. – JimmyJames Aug 16 '16 at 14:46
  • 11
    How long will it take? I'm 60% certain we can finish it by x, but theres a 10% chance it will take five times as long. – David Aug 16 '16 at 14:49
  • 19
    @David: This would probably drive the PM crazy because he knows from experience that this 10% chance actuall happens 80% of the times :) – Frank Puffer Aug 16 '16 at 14:54
  • 7
    The reality is many places would love to track a project into the ground then succeed unexpectedly. The PMs are often rewarded for having accurate projections so they have perverse incentives. This is the [principal-agent problem](https://en.wikipedia.org/wiki/Principal%E2%80%93agent_problem). – Sled Aug 16 '16 at 15:28
  • @ArtB Having accurate (not necessarily precise!) projections is extremely valuable. Accurate projections aid business decisions and also help other downstream processes (deployment, support, marketing, sales). – Eric Aug 16 '16 at 16:44
  • 1
    @Eric I see a general lack of understanding of accuracy and precision. Many people, in my experience, think they are synonyms. It's hard to have meaningful conversations about estimates when people don't understand how precision and accuracy are related or how much precision is needed and what is reasonable. – JimmyJames Aug 16 '16 at 17:28
  • 2
    `The primary objective of project management is the same as for developers: To deliver value for the product owner.` No, is not. Project management is RISK management and the estimates ARE a risk. If a project manager is unable to estimate within a budget --with certain probability- is doing a bad job. – Sergio Aug 17 '16 at 08:14
  • 3
    @Sergio And that contradicts what Jacques said... how exactly? Are you saying that making a great product within budget gives no value to the product owner/customer? – Luaan Aug 17 '16 at 12:43
  • @Sergio `If a project manager is unable to estimate within a budget --with certain probability- is doing a bad job.` But if a project manager pushes developers to work in an inefficient way guaranteed to create future maintenance nightmares because that makes it easier to estimate the development time, said project manager is also doing a bad job. – SantiBailors Aug 17 '16 at 12:57
  • @Luaan I'm saying that PMs do not add value to the customer in the same way as Devs. The primary objective of them (PMs) is risk management and that contradicts Jacques in the sense that is assuming that manual tests could be easier to estimate. That's an oversimplification, you can not simply add automated tests to any project, that's risk management and the PMs stands in favour of stake holders to reach completion on time and on budget, if that means code duplication (in the singular context of a project) so be it. – Sergio Aug 17 '16 at 13:17
  • @Sergio I think you're putting too much in what's written. Jacques *doesn't* assume manual testing is easier to estimate - one, he's talking about manual processes, and two, he quite explicitly mentions that he doubts that lots of slow manual processes would be easier to estimate. You're the only one who mentioned testing here :) And it's very rare that practices like this would result in being on time and on budget in the first place, much less low maintenance costs over the lifetime of the product. A good project manager is well aware of the uncertainties in estimates (the "risk" part"). – Luaan Aug 17 '16 at 13:28
  • 4
    @Sergio The point of this question is that predictability doesn't necessarily equate to reduced risk but because it's easier to plan around, there is a tendency of PMs (in my experience) to favor approaches that actually increase the risk of failure (as well as increasing costs and reducing value) because they make the math easier. – JimmyJames Aug 17 '16 at 13:30
  • @JimmyJames: If a PM genuinely prefers predictability to speed, then they could just pad the estimates, no need to compromise maintainability. – JacquesB Aug 18 '16 at 11:27
  • @JacquesB I actually didn't write that they prefer predictability to speed; you seem to have inferred that. I've seen situations where the current approach could not meet deadlines and the PMs would prefer to ask people to work 50% more hours a week than have the team find a different path to the goal. – JimmyJames Aug 18 '16 at 12:57
  • @JimmyJames: Eh yes, you literally wrote "there are a lot of lousy project managers out there that really do prefer predictability over speed or quality" – JacquesB Aug 18 '16 at 13:15
  • @JacquesB Sorry, I though you were referring to the comment just above. Let me try to put it together. The point is that PMs often prefer an approach that provides a even speed versus one that produces an uneven speed even if the sum of the uneven speeds is less. They want N% complete in each time increment. I once was staring at something like 10 months of work with 6 months to work on it (coworker quit.) I finished it in less than a month by producing 0% for 3 weeks. If I had been working with some of the PMs I've known (and been honest) they'd be livid for those first 3 weeks. – JimmyJames Aug 18 '16 at 13:30
  • @JimmyJames: You didn't do anything for three weeks and then finished a 10 month project in less than a month? Good for you! But it seems the project were overestimated to begin with, unless the coworker really was so bad his help would have made the development take ten times *longer*. – JacquesB Aug 18 '16 at 18:45
  • 1
    @JacquesB I wasn't doing nothing. I was doing a lot. I was a program to automate the work that was going to take so long. I didn't know how long it would take me but I was pretty sure it would be faster than what we had planned to do and absolutely sure we would have missed the deadline. It could have taken me 2 or three months and we'd still have been way better off. We didn't have project managers on that project, just technical leads so it wasn't an issue. Later in my career, PMs would complain to my manager in similar situations. – JimmyJames Aug 18 '16 at 19:05
  • 1
    Let us [continue this discussion in chat](http://chat.stackexchange.com/rooms/44167/discussion-between-jacquesb-and-jimmyjames). – JacquesB Aug 18 '16 at 19:15
  • @JimmyJames maybe this is the idea behind the perverse statement that "computers do not improve productivity"? Because we cannot estimate *how much* jet airplanes would be an improvement over horses, we would rather stick to what we know? (Substituting 'managers' for 'we', of course.) I think that the issue comes down to concrete vs abstract thinking, which is really the number 1 problem on earth at this point. But it is impossible to teach abstract thinking to adults, basically. They are stuck where they ended up around age 20. –  Mar 30 '18 at 13:32
  • I'm not familiar with the idea that "computers do not improve productivity". Is this something you hear or read frequently? – JimmyJames Mar 30 '18 at 13:48
39

You are right - copy-paste works great, and DRY has no point when your task is to produce a program for which either the copied template or the copy will not have to be maintained or evolved in the future. When those two software components have a completely different life cycle, then coupling them together by refactoring common code into a common lib which is itself under heavy development can indeed have unpredictable effects for the effort. On the other hand, when copying code sections inside one program or program system, all these parts will typically have the same life cycle. I will illustrate below what this means to DRY and project management.

Seriously, there are lot of such programs out there: for example, the computer game industry produces lots of programs which have to be maintained over a short period of some months or a year at maximum, and when that time is over, copy-pasting old code from a previous game where the maintenance period is exceeeded, into a new game's code base is perfectly fine and might speed things up.

Unfortunately, the life cycle of the most programs I had to deal with over the last years is very different from that. 98% of the requirements or bug fix requests which arrived me were change requests for existing programs. And whenever you need to change something in an existing piece of software, "project management" or planning works best when your testing and debugging efforts are quite low - which will not be the case if you change something in one place, but due to copy-pasted business logic you easily forget you need to change a dozen other places in the code base as well. And even if you manage to find all those places, the time to change them all (and test the changes) is probably much higher as if you have only one place to change. So even you could make an accurate estimation for the change, having the costs a dozen times higher than it needs to be can easily collide with the project's budget.

TLDR - whenever you develop a program where is no necessity or responsibility for bugfixing and maintenance of the original or the copy, feel free to copy. But if you, your team or your company is or might become responsible, apply DRY whenever you can.

Example

As an addendum, let me explain what "bugfixing and maintenance" means, and how this leads to unpredictability in planning, especially inside one product, by a real-world example. I have indeed seen these kinds of things happen in reality, probably not with 100 instances, but the problems can even start when you have just one duplicate instance.

The task: create 100 different reports for an application, each report looking very similar, some requirement differences between the reports, some different logic, but all in all, not many differences.

The dev who gets this task creates the first one (lets say it takes 3 days), after some changes or minor bug fixes due to QA and customer inspection its finished, it seems to run fine. Then he started to create the next report by copy-pasting and modifying the whole thing, then the next, and for each new report he needs ~1 day in average. Very predictable, at a first glance ...

Now, after the 100 reports are "ready", the program goes to real production, and some problems occur which were overlooked during QA. Maybe there are performance problems, maybe the reports crash on a regular basis, maybe other things do not work as intended. Now, when the DRY principle had been applied, 90% of those problems could be solved by changing the code base in one place. But due to the copy-paste approach, the problem has to be solved 100 times instead of once. And due to the changes already applied from one report to another, the dev cannot quickly copy-paste the fix for the first report to the other 99. He has to look into all the 100 reports, read them, translate the change to the modified report, test it, and maybe debug each of it individually. For the PM, this starts getting really hard - he can of course take the time for a "regular" bug fix (lets say, 3 hours) and multiply this by 100, but actually, this is most probably a wrong estimation, some of the fixes might be easier to make than others, others might be harder. And even if this estimation is correct, having the debugging costs 100 times as high as they needed to be will cost you company a lot of money.

The same will happen the next time when the customer asks for changing the color of his company emblem in all those reports, for making the page size configurable, or by some other new requirement which affects all reports in a similar manner. So if that happens, you can make an estimation for the costs and bill the customer 100 times the price he would have to pay when the code had been DRY. However, try this a few times and then the customer will cancel the project because he will probably not be willing to pay your exorbitant evolvement costs. And maybe at that point someone will ask the question why this happened and point with the finger at the person who made the decision for this copy-paste programming.

My point is: when you produce software for others, you have always at least for a short period of time the responsibility of making the thing work, fixing bugs, adapt the program to changing requirements etc. Even in a green-field project, these parts can quickly add up to far more than initially planned development effort. And especially when all your copy-pasted code is inside one product, the period of time of responsibility is for all parts the same, which is quite different from the situation where you copy-pasted some older code from a dead project which is no longer under active maintenance.

Doc Brown
  • 199,015
  • 33
  • 367
  • 565
  • 4
    Probably a good answer but way too verbose compared to other good answers. – Vince O'Sullivan Aug 18 '16 at 12:14
  • 4
    You may ignore DRY when "the copy will not have to be maintained or evolved in the future", but code that will never be used again often winds up getting used again anyway. – Andy Lester Aug 18 '16 at 17:32
  • "copy-paste works great..." - disagree! Even if the program is one-off and guaranteed to never evolve beyond the initial release, copy-paste code still makes it much more work and risk to fix bugs found during development of the initial version of the program. Unless you never make mistakes, in which case you are a God. – JacquesB Aug 18 '16 at 19:12
  • 1
    @JacquesB: you should read my answer more carefully, I did not write something different. – Doc Brown Aug 18 '16 at 21:15
  • Computer programming is *just different* from building identical machines with an assembly line. Huh. Who would have thunk it? Maybe we should have programmers working as PMs. But then we would need programmers as the managers. Programmers as the shareholders. Programmers as the customers... Shoot, just teach *everyone* how to program and be done with it. (In other words: non-experts are never going to understand the vicissitudes known by experts.) –  Mar 30 '18 at 13:37
19

So from a project management perspective, it is great to solve a task by copying some existing code 100 times and make some minor adaptations to each copy, as required. At all times, you know exactly how much work you have done and how much is left. All managers will love you.

Your base assertion is incorrect.

The thing that makes software different from other professions is that you're making something new every day. After all, no customer is going to pay you to build something that someone else has already made. Project managers might like predictability, but their bosses like value. If you're just copy-pasting code with slight variations, you're not providing much value for the company.

Eventually the company will realize they can do the same work in a fraction of the time by hiring a good programmer. And if they don't, their competitors will.

Telastyn
  • 108,850
  • 29
  • 239
  • 365
  • 2
    I'd argue most engineering professions are about "making something new every day" – BlueRaja - Danny Pflughoeft Aug 16 '16 at 22:48
  • 12
    @BlueRaja-DannyPflughoeft: Not really. Having worked as an electronics/electrical engineer I can testify that most big scale engineering professions (those projects that require commissioning like building ships and powerplants) are about making sure people doing something tried and tested do it properly. That's what business consider "engineering". Making something new is "R&D" – slebetman Aug 17 '16 at 00:01
  • 3
    @slebetman Maybe you just didn't notice all the work your management was doing; even when you're doing the same thing again and again, the environment changes every time - you don't have a template of a power plant that you can just deliver to a customer and be done with it, you need to do surveying, figure out how to supply the plant with raw materials and carry the product back out, manage all the raw materials for the construction and deal with supply issues and work shortages and a million other things. It *looks* like template work (as many software efforts do), but it really isn't. – Luaan Aug 17 '16 at 12:47
  • 1
    @Luaan: Yes, but none of that is making something new. All of them are "doing something we know how to do". Software development is different. Primarily because in software, unlike physical engineering projects, we tend to encapsulate things we already know how to do in libraries so we don't have to manually "do the surveying" etc. We'd just import a library for that and use it. – slebetman Aug 17 '16 at 20:42
  • 2
    @slebetman Almost all of software being written is "something we know how to do". Libraries *also* live in an environment that always changes. And you don't have 100% knowledge and experience with the whole library, and all the dependencies of that library and the other dependencies you have, and there's plenty of weird systems and hardware configurations that simply refuse to work the way a reasonable system should work. Encapsulation is great, but it's still expensive as hell and needs tons of surveying. And engineering has encapsulation too - prefabricated blocks, ICs etc. – Luaan Aug 18 '16 at 07:33
  • "After all, no customer is going to pay you to build something that someone else has already made." This statement is misleading. Sure, in a *very* strict sense, it's true, but there are businesses whose model is to create multiple copies of very similar software products by copying a template and then customizing. That's what produces situations like [this one](http://programmers.stackexchange.com/q/302147/92517). That obviously isn't a *good* way of managing the change, but the point is that "customizing a base product per customer" does exist. – jpmc26 Aug 18 '16 at 16:43
  • @Luaan As a former civil engineer, many of my projects (including industrial plants) were "copy from existing projects as much as possible." We'd site survey, review project-specific requirements, and then borrow heavily from a project we'd already done that was basically the same. "Boilerplate" exists for a reason in any field - of course you need to fill in the details and make tweaks, but good project management (and engineering) involves reusing a proven process while making refinements for the specific job. But I do agree that figuring out the daily details is creative work. – brichins Aug 18 '16 at 23:30
  • So "software engineering" is simply a contradiction in terms. Either we are creating something new, or we are reusing proven existing stuff. My understanding of software is that we are creating something new, something which probably has never been done before. Otherwise just use SAP and move on. –  Mar 30 '18 at 13:47
12

Cut-and-paste programming eventually leads to abandoned software. I was a contractor on a system for ordering wireline services from a very large phone company. The system was cut-and-pasted ad nauseum because all the testing was manual and they didn't want to change any working code. The tiniest enhancement could result in a new copy of hundreds of lines of code. Originally the application was written to handle accounts of up to twelve physical lines. Of course this limitation was made in hundreds of locations in the code. After about four years business asked the team what it would take to handle larger accounts. They estimated about $18 million. At that point the project was turned over to an offshore team for minimal maintenance. The existing team was all laid off.

Organizations that think this way are getting crushed by companies with better technology.

kevin cline
  • 33,608
  • 3
  • 71
  • 142
  • It think it is better brains, rather than better technology. Technology comes from brains, right? Whatever happened to "Think Smarter, not harder"? –  Mar 30 '18 at 13:49
10

An oft forgotten maxim that applies here is the rule of 3. This states, that it is OK to copy code once, but beyond that it should be replaced by generic code.

3 might seem like an arbitrary number but a common scenario is where data and logic are duplicated in an application and database. A example often cited is where there is a lookup table in the database and an enumeration client side. The difference in paradigms don't allow this to be readily stored in a single place and so the information often appears in both places.

Whilst it is nice to have DRY code, there can be times when business logic dictates an exception and so you have to create two or more bits of code from source that was generic before.

So - what to do? Code for the status quo (after all, YAGNI). Whilst code should be written for ease of modification, writing a whole raft of bells and whistles for something that might not be needed is just torching money.

Robbie Dee
  • 9,717
  • 2
  • 23
  • 53
  • 6
    Note that this does mean you should comment that you have copied the code (in both places) so that you know if you're about to copy it again, you shouldn't! – Mark Hurd Aug 17 '16 at 05:51
  • 3
    I've done this in a case where two classes needed the same method but were barely related -- kind of like distant cousins. I would have had to add dependencies to almost a dozen classes to have them actually share the code. So I did like what Mark suggested - copy-pasted the method and also left a big, obvious comment which pointed out the other location for that method. – Jeutnarg Aug 17 '16 at 20:42
8

In your question, you only list three functions of project management - estimate, schedule, and control. Project management is about achieving goals within the constraints of the project. The methods used to achieve goals within the constraints of a project are different for software projects than many other types of projects. For example, you want manufacturing processes to be highly repeatable and well-understood. However, software development is mostly knowledge work - it's non-routine and requires thinking rather than following rigid instructions and procedures. The techniques used to initiate, plan, execute, monitor and control, and close a software project are going to need to account for the type of work that needs to be done on a software project - specifically, non-routine work that cannot be done to specific instructions and procedures.

I think the other problem is that you are taking DRY, a concept that relates to repetition of information, and trying to apply it to managing tasks. DRY simply says that you should only have one authoritative representation of information. Project managers should be embracing this, since it means that everyone will know where to go for the information, communicating changes will be easy, and the changes can be controlled and managed well. DRY, through reusable pieces, helps to keep long-term costs down, helps to maintain long-term schedules, and to improve quality - three pieces to the Project Management Triangle. There needs to be some investment of time and money spent to effectively make things DRY, but the job of the project manager is to make trade-offs of time, cost, schedule, and quality.

Thomas Owens
  • 79,623
  • 18
  • 192
  • 283
  • Sure, software development is knowledge work. Actually I wouldn't even consider my 1st example (copy/paste) to be software development in a strict sense. Still, managing this type of work is much tougher, so the PM, even if he has a development background and knows all of this, in his role as a PM he tends to ignore it. (I don't say that this is a good thing, it is just what I have observed many times. I also don't think that those PMs are stupid or incompetent. It's more like the role sometimes forces them into acting like this.) – Frank Puffer Aug 17 '16 at 08:19
  • 3
    @FrankPuffer I disagree that the role of project manager forces the person into making particular decisions. It's more likely an educational or organizational force. From what I've seen, most project management education focuses on more traditional project management techniques (probably because they are more commonly applicable to more projects) than software project management techniques. This can bleed into organizations that expect this and don't look at other techniques for managing knowledge work projects like software development. – Thomas Owens Aug 17 '16 at 09:36
  • 2
    @FrankPuffer Sure it's tougher, but it provides more value. If your boss' boss is smart enough, he will get rid of the manager that tries to "make things easier for himself" and find someone who can actually do his job. Don't get me wrong, if making things easier provides value, go for it - but in what you describe, this is almost certainly to the *detriment* of the end value. – Luaan Aug 17 '16 at 12:50
4

Writing new code is just a small part of the task

Your suggestion would make it easier to estimate the part of initially writing new code. However, for actually bringing anything new (no matter if it's a brand new system, an addition of feature or a change of functionality) doing this is not sufficient and is just a minority of work - the estimates seen in literature tell that in practice this part is something like 20%-40% of the total work.

So the majority of work (which includes adapting your initial development to what was actually needed, integration, testing, rewriting, re-testing) doesn't get easier to estimate; just the other way around, intentionally avoiding DRY just made that part much larger, harder and with more variable estimates - that bug or need-for-change which requires changing all the cloned parts may not happen, but if it does, then your estimates are going to be totally wrong.

You don't get better estimates by improving your estimation quality of a small part of work but making it worse on a large part of work; so it's not really a tradeoff but a lose-lose situation where you get worse productivity but also worse estimates.

Peteris
  • 1,097
  • 6
  • 9
  • That's a good point. However, DRY or similar principles also apply to other tasks like testing or integration. Most things can be done in a mechanical way, without much thinking or in more intelligent ways. The intelligent solutions are often much faster but they involve a risk of failure. Plus, you have to put a fair amount of work into them before getting any result. – Frank Puffer Aug 18 '16 at 07:38
  • There is no "risk of failure", there is a *certainty* of failure. Everything will fail sooner or later. You are just choosing how expensive the hearse is and how fast you drive. –  Mar 30 '18 at 13:55
4

DRY is useful but it's also over-rated. Some people can take it too far. What many developers fail to realize is that anytime you implement DRY to use the same method for two (slightly) different purposes, you are introducing a kind of very tight coupling between the different uses. Now every time that you change the code for the first use case, you have to also check whether it regresses the second use case. If these are broadly independent use cases the it's very questionable whether they should be tightly coupled - they probably should not be.

Over-use of DRY can also lead to God-methods that explode in complexity to handle all the different use cases to which they are put, when generally smaller atomic methods that replicate some code would be much more maintainable.

However, I would suggest that the question isn't really relevant at a project management level. A project manager really won't want to concern themselves with this level of implementation detail. If they are it's probably micro-managing. Really... how things are implemented is more the responsibility of the developer and technical lead. Project management is more concerned with what gets done and when.

EDIT: per comment, I do agree however that insofar as making it easier to estimate development time, avoiding DRY can sometimes reduce the amount of uncertainty. But I believe this is an insignificant issue in relation to the more pressing questions of (1) how long until business requirements are met, (2) what technical debt is taken on board in the process, and (3) risks to total cost of ownership of the architectural choices made - whether to go DRY or not in many cases is a design choice that should be based more on risk/reward to those factors, than to whether it makes it a little easier to provide project managers with more accurate information.

Bradley Thomas
  • 5,090
  • 6
  • 17
  • 26
  • Of course the project manager should not deal with implementation details. That's not my point. My point is that, depending on the way a developer implements something, he is either more or less able to provide the information required for project management. – Frank Puffer Aug 18 '16 at 19:34
  • It doesn't make sense to me to damage/constrain the product or build in technical debt simply in order to be able to report on it better. The value of the report must surely be orders of magnitude lower than the value of quality work. But YMMV – Bradley Thomas Feb 15 '17 at 13:53
  • Maybe programmers should be paid orders of magnitude more than managers? –  Mar 30 '18 at 13:56
2

I think you are misunderstanding DRY.

Let's use an example:

public Class A
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }
}

public Class B
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }

    public int Add(int x, int y)
    {
        return x + y;
    }
}

vs.

public Class C : A
{
    public int Add(int x, int y)
    {
        return x + y;
    }
}

By replacing class B with C we have followed the DRY principle and reduced code duplication. But we haven't increased the unknowns or risk to the project (unless you have never done inheritance before).

I think what you mean when you talk about DRY is something more like a design task. I.e.:

public Class A
{
    public int Multiply(int x, int y)
    {
        return x * y;
    }
}

!!!New requirement! Some clients need to be able to multiply doubles!!

// Use class B for new clients!!
public Class B
{
    public int Multiply(double x, double y)
    {
        return x * y;
    }
}

vs.

public Class A // Version 2
{
    public int Multiply(int x, int y)
    {
        return Multiply(x as double, y as double);
    }

    public int Multiply(double x, double y)
    {
        return x * y;
    }
}

Here (assuming it works) we have designed a solution which can deal with both the old AND the new requirement, essentially trying to create a mathematical model of the real life problem or business rules. In real life the system we are modeling will obviously be much more complicated, our model of it won't fit exactly, and the edge cases and unexpected results will take time to find and correct.

So, should we take B or A version 2 in this case?

  • B is going to be more specific to the actual requested change with fewer side effects and be easier to estimate and quicker to do.

  • A version 2 will result in less overall code going forward and will be the more elegant solution

Again I'm going to say it comes down to the quality of the specification and requirements.

If we have very clear specifications which cover the edge cases and backwards compatibility then we can be sure we understand the system well enough to refactor the model without producing bugs.

If we have an emergency request for a single customer where the only requirement is that behaviour changes for that customer without consideration of the overall system; then 'improving' the model by refactoring A carries a substantial risk. Both of breaking other customers or overrunning the deadline because of the extra unknown time needed to design and test the solution.

Peter Mortensen
  • 1,050
  • 2
  • 12
  • 14
Ewan
  • 70,664
  • 5
  • 76
  • 161
  • 7
    I don't agree. Inheritance is not something you do once and then master it. There are lots of pitfalls. There are reasons why composition should be preferred over inheritance. So we have to make a decision: Inheritance? Composition? Something else? This decision will probably be difficult in the real world. In the second example there are also lots of alternatives. What about generics/templates? Ore maybe some functional approach using lambdas? Again: Lots of possibilities each of which will have specific implications. – Frank Puffer Aug 16 '16 at 18:55
  • 4
    The point is in the first example you literaly remove duplicate code through whatever method. but the exact same code executes either way. So there is zero functionality change. In the second example you change the approach to something which you hope is functionaly eqivilant but is actualy different code – Ewan Aug 16 '16 at 22:34
  • 1
    I was in a situation where your "emergency request" was the norm. The company I worked for created customized data systems for many different customers. At first they created one system with Cobol, then copied it for the next customer, etc, until they had 100 customers. Now they had a job on their hands trying to make systematic improvements and updates. I was working on a system which could replicate the behavior of most of these systems, using a single set of source code, but customizations stored in configuration data. We could not do everything, and some things could not be added. –  Mar 30 '18 at 14:01
1

Paragraph by paragraph

One of the most basic and widely accepted principles of software development is DRY (don't repeat yourself). It is also clear that most software projects require some kind of management.

Correct.

Now what are the tasks that are easy to manage (estimate, schedule, control)? Right, repetitive tasks, exactly the tasks that should be avoided according to DRY.

Repetitive tasks should be automated, mandatory. They are boring, error prone, when made by hand.

So from a project management perspective, it is great to solve a task by copying some existing code 100 times and make some minor adaptations to each copy, as required. At all times, you know exactly how much work you have done and how much is left. All managers will love you.

I think you can change the word "adaptation" with "configuration". Consider you have a bug in this piece of code that is supposed to be copied. A bug that appears under specific conditions. If it is not fixed in the original source, and it is copied there will be a lot of places to fixed. This may be bad, but then someone has to:

  • first fix the code in the original source;
  • fix the code in every other place;
  • make sure that those were all of the places. When you say this had to be done to the manager, he will probably at least hate someone.

If instead, you apply the DRY principle and try to find an abstraction that more or less eliminates the duplicate code, things are different. Usually there are many possibilities, you have to make decisions, do research, be creative. You might come up with a better solution in shorter time, but you might also fail. Most of the time, you cannot really say how much work is left. You are a project manager's worst nightmare.

Removing duplications leads to single point of failure. If something fails you can be pretty sure where this happens. S.O.L.I.D. and Design Patterns are there to help to fix exactly that problem. Too short deadlines tend to provoke procedural style "coding". More time invested in one project in order to create something reusable means there should be minimal amount of time spent in the next project when the feature will be reused, but it should be configurable in first place.

Of course I am exaggerating, but there is obviously a dilemma. My questions are: What are criteria to decide if a developer is overdoing DRY? How can we find a good compromise? Or is there a way to completely overcome this dilemma, not just by finding a compromise?

A lot of people pointed there is no dilemma here. Yes and no.

If you have something highly experimental that has never before being done - there is no dilemma. Otherwise if you have something that has to be done again, like new booking system you already have abstractions, just depends what you need.

I think the dilemma is - should we implement a something in a feature, if it is unlikely to be requested. Implement something when requested. Nobody needs a huge infrastructure that won't be used.

Bakudan
  • 131
  • 7
  • Implement something the simple, fast way now, because that was requested. Later, when complex way is needed, original effort is for nothing, have to start over. Manager does not like this. As if you said, "The time spend driving west was useless if now we need to go east." But going all the way around the world the first time just so we could go east all along is also wasted time. –  Mar 30 '18 at 14:57
1

this is not at all about designing for future reuse or about the YAGNI principle. It is about repeating code in the current work package.

It absolutely is about design. Maybe not re-use per se, but design nonetheless.

What are criteria to decide if a developer is overdoing DRY?

Experience and your existing environment/situation. For a given problem you will get a strong sense of the Prado Principle as you attempt greater degrees of DRYness. Then suddenly management considerations come to play. Time, goals, the customer, long term code management (someone said technical debt), etc. will inform your plan of attack.

How can we find a good compromise?

Uh... design? Refactoring is design, well it is supposed to be. The scope of the DRYing can easily expand like a super nova from the loop, to method, to class(es). Been there, done that. But you can't really know until you study the problem - this is design.

How can it not be a design problem? You must consider the problem more widely than the immediate duplicated code at hand. This is a design activity whether it's existing code or a blank sheet; whether it's "extract method" or creating new classes and modules.

Epilogue

... the referred question and its answers do not cover the project management aspect.

Typical management, ignoring design time. We would have, ideally, designed out the superfluously redundant repetitiveness prior to coding. Instead, management thinks development (and bug fixes) is a single Olympic event - coding - when it is in fact a decathlon. And they measure to 1/1000 of a second because they think it's all analog.

If instead, you apply the DRY principle and try to find an abstraction that more or less eliminates the duplicate code, things are different.

I had this experience: "I spent two days writing this row (of a GUI form) and two hours writing the rest of the form." I mean that I took the time to identify reusable classes - DRY being a natural side effect- the GUI form row and w/in that some others. Once debugged these were used, individually and in composition, throughout the form which now coded very fast and testing was exceptionally quick despite building-up complexity. And it flew through formal testing too with amazingly low bug rate.

Most of the time, you cannot really say how much work is left. You are a project manager's worst nightmare.

I didn't know either but I had faith the up front design effort would pay off. We all say this but management in particular doesn't trust it. Management would have thought I was screwing around. "Two days and you don't even have 2% of it coded yet!"

In one case we stuck to our guns when management said "you're spending too much time in design, get going." And co-workers saying "it's too many classes." Well, a far less complex sub-project was supposed to take about 1 month (I thought it was OK ballpark guess) but took 5 months. 3 months of that was in testing/fixing because it was such a POS. "But we didn't have time to design!". They actually said that.

My questions are: What are criteria to decide if a developer is overdoing DRY? How can we find a good compromise? Or is there a way to completely overcome this dilemma, not just by finding a compromise?

Show management how it works out. Capture some data. Compare to other work, especially that of your co-workers who do the slap-dash rush job. That pile of failure always seems to lose the race, getting stuck in test and then after release returned over and over to fix more bugs.

radarbob
  • 5,808
  • 18
  • 31