37

Say you've just started working in a very small team on a {currently relatively small, though hopefully bigger later} project. Note that this is an actual project intended to be used by other developers in the real world, not some academic project that is meant to be scrapped at the end of a semester.
However, the code is not yet released to others, so no decision is yet set in stone.

The Methodologies

One of you likes to begin coding and make the pieces fit together as you go before you necessarily have a clear idea of how exactly all the components will interact (bottom-up design). Another one of you likes to do the entire design first and nail down the details of all the components and communication before coding a solution.

Assume that you are working on a new system rather than mimicking existing ones, and thus it is not always obvious what the right end-design should look like. So, on your team, different team members sometimes have different ideas of what requirements are even necessary for the final product, let alone how to go about designing it.

When the bottom-up developer writes some code, the top-down developer rejects it because of potential future problems envisioned in the design despite the fact that the code may solve the problem at hand, believing that it is more important to get the design correct before attempting to code the solution to the problem.

When the top-down developer tries to work out the full design and the envisioned problems before starting to write the code, the bottom-up developer rejects it because the bottom-up developer doesn't think some of the problems will actually arise in practice, and thinks that the design may need to be changed in the future when the requirements and constraints become clearer.

The Problem

The problem that this has resulted in is that bottom-up developer ends up wasting time because the top-down developer frequently decides the solution that the bottom-up developer has written should be scrapped due to a design flaw, resulting in the need to re-write the code.

The top-down developer ends up wasting time because instead of parallelizing the work, the top-down developer now frequently sits down to work out the correct design with the bottom-up developer, serializing the two to the point where it may even be faster for 1 person to do the work than 2.

Both of the developers want to keep working together, but it doesn't seem that the combination is actually helping either of them in practice.

The Goals

The common goals are obviously to maximize coding effectiveness (i.e. minimize time wastage) and to write useful software.

The Question

Put simply, how do you solve this problem and cope with this situation?

The only efficient solution I can think of that doesn't waste time is to let each developer follow his/her own style for the design. But this is harder than it sounds when you code-review and actually need to approve of each others' changes, and when you're trying to design a coherent framework for others to use.

Is there a better way?

  • 12
    To me it sounds like the "top down" guy wants to do Big Design Up Front. While "bottom top" guy just wants to start hacking and get to the solution incrementally. – Euphoric Jun 29 '16 at 4:50
  • 24
    Both are correct. You need to find a compromise that both agree on. One side needs to learn that some design up front might save time in the long run. Other side needs to learn that at one point, it is beneficial to stop thinking and start working. – Euphoric Jun 29 '16 at 5:34
  • 8
    @Euphoric: I love this. One person says both are wrong, one person says both are right, one says they need to compromise, one says they should break down the tasks into parts and just work on different things. The message I'm actually getting is that nobody really knows what the right approach is! – Mehrdad Jun 29 '16 at 7:22
  • 4
    The word "communication" comes to mind. – Bryan Oakley Jun 29 '16 at 12:30
  • 4
    Who is the manager? Who makes the decisions? – corsiKa Jun 29 '16 at 16:13
55

Obviously they are both wrong.

The bottom up guy is hacking away at code and will never produce something that does what it is supposed to do - it'll be a continual churn as the unknown requirements are determined.

The top down guy can spend just as long on architectural vision and get nothing productive done too.

However, a middle ground is ideal - if you know the goals you're working towards (which you get from a broad design work) and get on with coding it (without any detailed planning) then you reap the rewards of a system that is both organized and efficiently developed.

It's called Agile by the way (not the BS version of agile that some people practice where procedures are more important than working software) but true agile that gets on with working towards a commonly-described and understood end goal.

To fix the problem here, try an Agile approach (Kanban is probably the best) which will both force the top-down guy to do some work, and will force the bottom-up guy to do planning on what he's trying to achieve.

  • 10
    +1 for the BS version of agile. There are so many people getting agile wrong nowadays... – T. Sar Jun 29 '16 at 12:53
  • 17
    I don't know if your answer is just getting upvotes because of the sensational "they are both wrong" in the beginning, but the rest of it seems to rely on wrong assumptions. Notice in the question I said the two people might even be more productive individually than working together. So it certainly isn't the case that the top-down developer isn't getting any real work done. Similarly, it's also not like the bottom-up developer isn't producing something that does what it is supposed to do. Rather, the two style are just clashing when they work together because of how the problem is approached. – Mehrdad Jun 29 '16 at 15:50
  • 18
    @Mehrdad well, most people are faster when working individually, but you get better software when working together - as a quote said "if you want to go fast, travel alone. If you want to go far, travel together". So you asked how to make these guys work well together - and I gave you an answer that I think would work, it constrains them both into collaboration without forcing them to work as one - a common dev methodology that both would be happy following. You said yourself their conflicts are affecting their productivity. – gbjbaanb Jun 29 '16 at 16:39
  • 1
    @Mehrdad The answer you need but don't deserve right now ;) – Insane Jun 29 '16 at 20:11
  • 2
    @ThalesPereira What is "BS version of agile" ? – Sjoerd222888 Jun 30 '16 at 7:46
23

The two developers need to maintain a mutual respect for each other.

The top down person needs to respect the fact that the bottom up person may have come up with something that actually works. As one of my "quant" professors told me, "A working model is worth 1000 guesses." If that's the case, the top down person should consider re-doing his "design" to accommodate the bottom up person's work.

The bottom up person should also respect the top down person's "framework," and realize that it can be good for avoiding wasted effort, solving the wrong problem, getting off-topic, etc. The bottom up coder should at least keep in mind what the top down person is trying to do, and try to address at least the top downer's concerns, as expressed in the framework. That would be true even if the bottom-upper disagreed with portions of the framework itself.

7

You can minimize the loss of time spent by each developer if you break apart large tasks into multiple smaller and more focused ones. Have them work closely together so that neither of them get too far ahead of the other. Short sprints, and small deliverables go a long way. It's easier to fix a small mistake than a big one.

It might seem counter intuitive to your goal, but pair programming works. There are things you just won't catch by yourself right away, sometimes for hours or even days. If working directly on tasks together is out of the question, try code reviewing/standups more frequently throughout the week.

Keep everyone informed!

If you are seeing devs throw out code because they were off in their own world, you need to catch and reconcile the conflicts as quickly and efficiently as possible. Your boss will appreciate it, and the team will appreciate not having to throw out a week's work because he didn't know what the other guy was doing.

You should also see them working together as a blessing. The fact that they are working together and fixing their mistakes as they go is a good sign. I made it halfway through your post thinking "man these two probably hate each other..." and to my surprise you said they want to keep working together.

I think this quote is appropriate given your scenario.

"If two people agree on everything, one of them is unnecessary." ~ Some Old Guy

7

This actually sounds like an ideal scenario to me. Then again, I am both of those developers at the same time. I like to draft out the "big picture" in the form of notes that eventually find their way into an issue tracker. Then I start thinking about the implementation details from the bottom up. The big picture evolves as I gain a better understanding of how the pieces will fit together, and the pieces evolve as the requirements change and I get new ideas.

Maybe that's a good model for multiple brains.

  • 5
    I find GitHub's Issues to be an amazing win-win for stuffing aside random ideas for future features, potential problems, notes to self, etc. It gets them out of my head, but in a way where I can be confident I'll be able to find them later. – hBy2Py Jun 29 '16 at 19:59
6

In my opinion, they are complementary profiles and may end up doing very well. Both coding and designing are necessary phases in programming and you don't want to end up in a team where nobody wants to do X, all you need is a bit of organisation (see I can have a bold word too !)

This can be done through supervision as others pointed out, but even better done by mutual agreement on an iteration schedule of when to design and when to code, and avoiding in general to code what is currently under design.

Bonus point, as soon as a project is splat in smaller modules, the top-down programmer can design stuff the bottom-up programmer isn't currently working on, making it a phase where both do as they like. This however implies an ability from both of them to make necessary adjustments when the time comes to put everything together.

  • 1
    +1 since the last one is an actionable solution in some cases, but it's actually not really viable here. The issue is the bottom-up programmer wants to contribute to the design too, and the top-down programmer wants to contribute to the code too. Splitting the two task-wise would make sense in a company where you have managers, PMs, developers, etc. but in a small team like this where everyone wants to work on the whole system it would make neither of them happy to split the tasks like that. – Mehrdad Jun 29 '16 at 8:24
  • 2
    Ideally, both would work on both design and coding, that's why having a schedule, even if your team is small, is good. Just plan some "meetings" when both can spin questions and contributions about how to design/implement modules, and allocate time for the next task and plan the next meeting. Agile-like except you don't have to call it as such ;) – Arthur Havlicek Jun 29 '16 at 8:34
  • Unfortunately, in such cases, the top-down guy will create plans, and the bottom-up guy will ignore them. ie. both will continue to do their own thing. – gbjbaanb Jun 30 '16 at 15:26
5

One note: you said

Assume that you are working on a new system rather than mimicking existing ones, and thus it is not always obvious what the right end-design should look like.

This is part of the problem: Unless you're working on a tiny project for an already solved problem, there isn't actually a right end-design. There's lots of possible designs. Keep in mind that unless you're doing this for an ego boost due to the beauty of your code, the end goal is a working app. That's it. How you get there is irrelevant, and the best way to let these two go fast is to get them working together, in a complementary fashion.

Like others have said, both views can be correct in certain ways. It's far from unusual for two devs to disagree on practices, especially for something as subjective as design and development processes. You've got two people here who are passionate about what they do, and knowledgeable about how to do it: embrace that!

There is a great potential here for you to allow both people to work in their own way, and still match up the pieces to get a working application.

  1. I'd have the two of them sit down and discuss, encouraging them to see it from the other's point of view.

  2. After that discussion, you can start talking about planning: this should be done as a team, with the understanding that neither has to 'concede' to the other, but compromises will need to be made. There are plenty of ways to plan the architecture for a codebase that allow it to be extended rather easily later, without introducing a ton of extra code.

  3. Once you can get them to come to some kind of truce, let them run wild! Let the 'top down guy' drive planning the high level architecture, interfaces, hierarchies, etc. Let the 'bottom up guy' jump in and start writing code once there's a couple of modules planned. Get them to formally agree to accept the other's methods as good for the overall project: Planning to allow for easy future changes is good, but it doesn't have to be coded that way right away. Create interfaces and stub out methods to get the structure of the code, and accept that a good bit of the code for the future will not actually be written until needed.

  4. Have them review both design and code frequently, together. Iterate through cycles where you dive deep into some segments of the architecture, plan in more detail, and write those parts.

  5. This is probably the most important point: Facilitate points in the cycle where they talk about process only, rather than the work being done. Reflect on the dynamic being built: there are four questions you should be asking. What went well that we should keep doing? What went poorly that we should stop doing? What are we missing? What can we do about what we're missing?

This will take some work: you have to get them to agree to work together in their own ways. It's not easy for some people to admit that there's not one single, correct way of doing things. The important thing isn't which way you work, or what the code looks like in the end; the important thing is that these two skilled, knowledgeable people learn how to work best together. It's not something you can just tell them; all you can do is guide them through a process of learning how to do it themselves. Just like there's no one right design, there's no one right way for people to work.

4

Generally, in my experience over my career, there is insufficient design up front. And the design that does happen up front is low quality. This is Bad. Mostly because the result is (to a greater or lesser degree) throwing mud at the wall and seeing what sticks. Technical debt gets baked in from the get-go.

Top-down is generally superior to bottom-up. Although I would not rule out bottom-up entirely. The reason for this is that top-down forces you to think about the problem more broadly and ask better questions. This reinforces the first point above... leads to higher quality design and usually heavily influences much of the lower level work. This reduces considerable re-work that is often otherwise necessary if the lower level components are built first.

There is a not-insignificant risk that if bottom up components are built first, development pressure tries to mold business requirements to the components that have been engineered. This is also Bad. Business requirements should drive the design, which should drive the implementation. Anything going the other way will lead to inferior outcomes.

  • 2
    "There is insufficient design up front. And the design that does happen up front is low quality."- The typically low quality of up-front design is exactly the reason you don't see as much of it as you'd like. – user1172763 Jun 29 '16 at 18:56
  • 1
    +1 for "Business requirements should drive the design". In the absence of business requirements any upfront design is merely mental masturbation, however without business requirements then just hacking away will nearly always be a waste of time and potential discouraging waste of time and effort when you discover that you wasted so much effort on something that is useless. – maple_shaft Jun 30 '16 at 12:59
  • 1
    @user1172763 good quality design > low quality design > no design. Even the poorest design work contains some value in at least it gives a focus to vision, ie it acts to guide you in the right direction. No plans mean no direction means eventual chaos. – gbjbaanb Jun 30 '16 at 15:29
4

Neither approach is sufficient. It seems that each of them is clever or experienced enough to realize the short-comings of the other approach (maybe they got burned?) but fail to see the short-comings of their own selected approach...

The truth is, a mixed approach is necessary:

  • it's nearly impossible to come up with the "right" design upfront; a degree of experimentation is necessary to identify the pain points, bottlenecks, ... (hint: they are never where you think they will be)
  • it's nearly impossible to go anywhere by just "going", you're more likely to end somewhere you didn't want to, or just run in circles, than anything

Mixing both, however, you can:

  • have a rough sketch giving directions and a skeleton of infrastructure
  • and developing components fitting this vision

Because no existing system fulfilling this purpose exists, it is important to realize upfront that:

  • experimentation/prototyping will be necessary
  • iteration, therefore, will be necessary

Therefore, emphasis should be put on reach a "working" system as soon as possible, even if this means ignoring corner cases, etc... This is the concept of the "thin vertical slice": instead of building the foundations of the house, then the walls, then the roof structure, ... and only obtaining something usable at the very end (or never obtaining it, or it nor really being usable)... it is better to instead build a fully outfitted room first, like the bathroom. It's usable immediately, and can be used to gather feedback.

In order for feedback to be valuable, though, it's best to tackle a core part first.


So, what do with your coworkers?

First thing first is that both of them need to understand the need for collaboration and the need to agree on a way forward: constantly getting rebuked, like they are, is bound to get on one's nerves and affect one's motivation. I've presented above what I've found to work well in practice on multiple projects, you may use it as suggestion.

Then, they need to agree on who does what. Note that in the middle ground approach underlined above, both of them should fine tasks that they appreciate.

Note that both building the skeletons and building the bricks is best approached incrementally.

  1. Both of them should get a rough sketch of the skeleton, and then decide together which "thin slice" to focus on first
  2. The bottom-up guy should start working on the best understood piece of "thin slice"
  3. The top-down guy should start fleshing out the skeleton, ideally tackling the most blocking pieces first for completing the slice

Rinse and repeat until you get the slice working; accumulate feedback along the way to tweak as needed.

Beware: this is a prototype, both need to be ready to throw it away and start from scratch on a completely different design.

  • Remove the 4 leading words, they are an unnecessary punch-line (and are in total contradiction with this otherwise balanced answer). – Tibo Jun 30 '16 at 13:06
  • 1
    @Tibo: You're harsh, if we can't even shake people a bit... :D – Matthieu M. Jun 30 '16 at 13:13
  • Agreed :) I tend to like shaking those who live in an ivory tower, hoping everything will shatter under their feet. -1 -> +1 btw. – Tibo Jun 30 '16 at 13:37
  • Finally, another person that sees the wisdom in getting an end-to-end prototype with minimal-yet-comprehensive functionality out the door as early as possible. Thanks for this answer, I enjoyed reading it. – Fuzzy Analysis Aug 2 '18 at 2:00
3

What you need is a leader (or supervisor) who understands software development, and who makes the decision about which approach should be used in the project. If necessary, the leader directs the developers to work in a particular way, irrespective of their personal preferences.

The only efficient solution I can think of that doesn't waste time is to let each developer follow his/her own style for the design.

Actually, it could be highly inefficient ... because the chances are that there will be lots of conflict and rework. Worse still, you may end up with a total project failure.

protected by maple_shaft Jun 30 '16 at 12:54

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

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