I've been working as an app developer for a year and a half now (not long I know), and I've just been given my first big project.

Needless to say it didn't go very smoothly, so I sought advice from a senior programmer involved in the project about how to approach it.

He said that I had drastically been over thinking the task at hand, and that because I had never tackled a project of this scale before I'd been spending too much time over thinking design patterns. In his wise words, he told me "F*ck the future, build for now".

Is this a trend programmers typically follow when going about a project like this? For example, if you were asked to do a proof of concept model, is it a typical trend just to mash a workable example out as soon as possible?

Edit: In light of the debate this has sparked, I'd like to mention that this situation is fairly extreme: we have very tight deadlines due to factors beyond our control (i.e. the market we're aiming for will lose interest if we don't show them something) and his advice proved to be very effective for this particular task.

that one seem more related to coding than design
–
Balog PalJun 5 '13 at 12:54

19

I +1-ed just for "F*ck the future, build for now". If he feels like endorsing this statement, I'll be glad to credit him whenever I add that to a commit log after I scrap something I dumbly overengineered (which happens way more than I'd like to).
–
haylemJun 5 '13 at 18:57

11

Reminds me of an old coworker who was always "gold plating" his apps with too much features, design overdose and things that weren't in the requirement at all just to "show off" or "preparing for a future that would never come". Very interesting question :)
–
Jean-François CôtéJun 5 '13 at 20:01

8

@Jean : The only projects where "a future that would never come" happens are programs that are failures (even if the project was deemed a success). If your program is successful then that means it is being used. If it's being used then users will want more features. If you adhere to the "build for now" philosophy then you get the current state of most software today. Utter garbage, difficult to change. The only reason developers can get away with it is because it is so prevalent. Developers who are skilled will build systems faster doing it correctly to begin with and don't end up with trash.
–
DunkJun 5 '13 at 20:17

50

Questions like this are like a Rorschach test. The OP doesn't supply enough information to know whether he is actually an over-designer or his mentor is an under-designer. In the absence of sufficient information, everyone sees what they want.
–
PeterAllenWebbJun 6 '13 at 0:16

9 Answers
9

Captain Obvious to the Rescue!

I'll be Captain Obvious here and say that there's some middle ground to be found.

You do want to build for the future and avoid locking yourself into a technological choice or a bad design. But you don't want to spend 3 months designing something that should be simple, or adding extension points for a quick and dirty app that will have a 2 year lifespan and is unlikely to have follow-up projects.

It's difficult to find the distinction, because you can't always predict the success of your product and if you'll need to extend it later.

Build for Now if...

the project is going to get scrapped

the project has a short life-span

the project should not have extensions

the project doesn't have a risk impact value (mostly in terms of image)

In general, in-house projects or something built for a customer should be developed for now. Be sure to have straight requirements, and relate to them as needed to know what's needed and what's not. Don't want to spend too much time on anything that's "nice to have." But don't code like a pig either.

Leave the General Problem for later, if it may ever be necessary and worth the effort:

Build for the Future if...

the project will be public

the project is a component to be reused

the project is a stepping stone for other projects

the project will have follow-up projects or service releases with enhancements

If you're building for something public, or that's going to be reused in other projects, then you've got a much higher probability that a bad design will come back to haunt you, so you should pay more attention to that. But it's not always guaranteed.

Guidelines

I'd say adhere to the following principles as best as you can, and you should put yourself in the position of designing efficient, adaptable products:

whenever you feel like scratching an itch and think of an addition, write it down. Look back at your project requirements and ask yourself if additions are priorities or not. Ask if they add primary business value or not.

I know that I personally tend to overthink and overengineer. It really helps to write ideas down and very often re-think if I need additional features. Often, the answer is no, or, "it would be cool later." Those last ideas are dangerous, because they stay in the back of my head, and I need to force myself not to plan for them.

The best way to code without overengineering and without blocking yourself for later is to focus on a good minimal design. Break things down nicely as components that you can later extend, but without thinking already about how they may be extended later. You can't predict the future.

Just build simple things.

Dilemmata

Overengineering

Is this a trend programmers typically follow when going about a project like this?

Prototyping / Quick-n-Dirty / Less is More

Is it a typical trend just to mash a workable example out as soon as possible?

It's a prevalent practice, but it's not how the vast majority of projects are approached. Still, prototyping is a good trend in my opinion, but one with a mean downside. It can be tempting to promote quick and dirty prototypes to actual products, or to use them as the base for actual products under management pressure or time constraints. That's when prototyping can come back to haunt you.

When to Use Prototyping?

[...] prototyping is most beneficial in systems that will have many interactions with the users.

[...] prototyping is very effective in the analysis and design of on-line systems, especially for transaction processing, where the use of screen dialogs is much more in evidence. The greater the interaction between the computer and the user, the greater the benefit [...]

"One of the most productive uses of rapid prototyping to date has been as a tool for iterative user requirements engineering and human-computer interface design."

On the other hand:

Systems with little user interaction, such as batch processing or systems that mostly do calculations, benefit little from prototyping. Sometimes, the coding needed to perform the system functions may be too intensive and the potential gains that prototyping could provide are too small.

And if you have a green monster around, just make sure to keep a prototype within budget...

I can't emphasize enough how important the points you've made about prototyping are. I don't think this is really what the question was about (mainly about when it's ok to stop and design, rather than just build as I understand it), but prototyping is definitely a relevant part of that process. Nice job!
–
Benjamin GruenbaumJun 7 '13 at 13:10

3

I'm quite puzzled as to why I'd get a downvote here. Please be kind enough to give information on that, so I can see the errors of my ways, sensei.
–
haylemJun 7 '13 at 15:58

5

I used to work with a mechanical engineer who put it like this: Do you want your product under-engineered or over-engineered? These are really the only two options.
–
Guy SirtonAug 14 '13 at 22:25

1

@SamtheBrand: thanks for the great edit. Much better.
–
haylemJan 18 '14 at 13:50

1

@haylem: sometimes I find putting ideas into issue tracking (if your project is large enough to have one) allows me to remove them from the back of my head. Knowing that they are visible to others in some way makes me feel like I don't need to constantly revisit them in my head (though there is a balancing act there too =]).
–
afuzzyllamaJan 20 '14 at 15:14

When you start out programming, everything is a proof of concept even if it is just to yourself. There are cases when an idea requires something quick and dirty or a prototype because time is a key factor. The massive fear among developers is stakeholders thinking the little app is ready for production or you should be able add features at the same rate forever. You work on a large project and find out this isn't the case.

Large projects usually have more complex requirements, so there is a temptation to try and implement complex designs. You'll spend a lot of time reading, researching and trying to implement them. This can become a big time waster, but it is all part of learning and gaining experience. Knowing when to use a particular design is difficult and usually comes with experience. I tried "that" on "this" project and it didn't work but now I see it should work over "here".

You have to plan and plan a lot, but don't do it all at once. It definitely doesn't have to be done all at the beginning. I'd rather see someone create their first large project like this:

Design and discuss a little bit.

Write a bunch of code that does something.

Recognize the problems and STOP coding.

Get serious about design and stop worrying about losing momentum or your code-mojo and ignore the project manager (You're doing him/her a favor.).

Get the project under control. Fix your messes. Make sure everyone understands the plan. Keep the project under control.

Sometimes you hit one of those features that really makes you concerned on how to implement it in the existing codebase. This is not the time to "just make it work". I had a boss who said, "Sometimes you have to grab a stool instead of a hammer." He told me this after he caught me "thinking" at my desk. Unlike a lot of bosses, he didn't assume I was goofing-off and made sure I understood he wanted me to do more of it. Genius.

Ultimately, your code is the design. It is supported by documents, diagrams, meetings, email, whiteboard discussions, SO questions, arguments, cussing, fits of rage and quiet chats over coffee. There is a point where you can't design any more and risk having to throw more design time away because of the flaws you will only discover trying to write the code. Also, the more code you write the better chance you will introduce a design flaw that you can't code your way out of. Time for the stool again.

Do programmers typically build something that works now without thinking about the future?

Yes.

Should they do so?

No.

At a first glance it would seem that "thinking about the future" violates established design principles like KISS and YAGNI, which claim that there shouldn't be implemented anything that isn't required right now.

But actually it doesn't. Thinking about the future means designing simple, extensible and manageable software. This is especially important for long-term projects. New features will be required with time, and having a solid design will make it easier to add new pieces.

Even if you aren't going to work on a project after you complete it, you should still develop it intelligently. Its your work, and you should do it well, at least in order not to forget how good work is done.

Although what you say makes a lot of sense my personnal experience tells me otherwise. Typically when devs get in the mode @F***k it... just ship it@ there tends to be a boat load of copy pasted code springing all over the place. The end result is utterly unmaintanable. Thinking ahead is not just about extentions and modifications but maintenance as well.
–
NewtopianJun 5 '13 at 15:25

Agile developers have a saying, "You Aren't Gonna Need it (YAGNI)" which encourages that you design for what you need now rather than what you think you might need in the future. To extend a design to work in the future, the recommended route is to refactor.

The important aspect to this is to keep the requirements for your product in your mind as you design, and to ensure that you are not designing for a bunch of requirements that might happen in the future.

There is something to be said for developers who can think two or three iterations ahead - they know their clients or the domain so well that they can anticipate future needs with high degrees of accuracy and build for them, but if you're not sure, it's best not to spend too much time on things that you or the clients don't need.

There are also other reasons for thinking ahead: that the functionality you are developing does not fit into one sprint. So, you either break it up artificially, or you refuse to implement any functionality that you cannot complete within a single sprint.
–
GiorgioJul 24 '13 at 17:39

+1 for mentioning refactoring. I can't believe none of the other answers so far mention this. YAGNI is only viable if you refactor.
–
Ian GoldbyJan 20 '14 at 12:54

Is this a trend programmers typically follow when going about a project like this?

I suspect what your mentor meant was that you shouldn't build in any additional complexity that may not be required by the final solution.

It is all too easy to think that an app should do this and that and get massively sidetracked.

As for design patterns, it is worth remembering that they're a means to an end. If you find with experience that a certain design pattern doesn't fit despite your earlier hunch, then this could indicate a code smell.

For example, if you were asked to do a proof of concept model, is it a typical trend just to mash a workable example out as soon as possible?

It is worth getting a steer before the project starts as to what milestones there are and whether they'll want to see a bit of everything (vertical slice) or just each part in detail as you develop it (horizontal slice). As part of the initial design, I find it worth story boarding the whole app so even though the code isn't written you can do a helicopter view of the whole thing or a deep dive of a given area.

He said that I had drastically been over thinking the task at hand, and that because I had never tackled a large project like this I'd been spending too much time over thinking design patterns. In his wise words, he told me "F*ck the future, build for now".

I think that's a bit of a cowboy mentality from the other developer. The modern day's version of a tough nerd who just "does it now". It's become a popular theme among startups and no thanks to people at Facebook for starting the phrase "getting it done is better than doing it right".

It's appealing. It's encouraging and offers visions of developers standing around a console clapping their hands as they launch their big project into the world on time, on budget and all because they did not over engineer anything.

It's an idealistic fantasy and life doesn't work this way.

A fool will rush into a project thinking he can just "do it" and get it done. Success will favor the developer who prepares for the unseen challenges, and treats his profession like fine craftsmanship.

Any senior developer can criticize, condemn and complain - and most do!

While he/she tells you that you are "over thinking" the project. I congratulate you on actually "thinking" first. You have taken your first steps in being a better developer then the other guy.

Is this a trend programmers typically follow when going about a project like this? For example, if you were asked to do a proof of concept model, is it a typical trend just to mash a workable example out as soon as possible?

That's exactly what a proof of concept is. It's an attempt to mash something out as quickly as possible so that people can take a step back and look at it. It's done to prevent mistakes, misdirection and wasted time/money.

There are many different kinds of proof of concepts. You can build something that is thrown away in the garbage when done, or you can build something that represents a starting point for the project. That all depends upon what you need, and how close the concept is to the final product.

It's also an opportunity to demonstrate your ideas. There have been times when I've presented a prototype that took things to a level they didn't expect.

Design is usually open-ended so it is way too easy to apply too much or too little of it. And you will know the correct amount only after the project is done or discarded. Or even not then.

There's no general recipe for success, but you can learn to recognize extremes. Complete design of everything up front hardly ever works beyond trivial stuff. It's okay to leave components for refining and just have a feeling that it can be done, or there's a way to discover problems early.

You may look up how incremental development works if you're not familiar. Successful methods usually are iterative on one or more levels, seek tight feedback and grow on some skeleton.

There are a few good reasons to listen to advice to stop planning and start coding;

After only 18 months as a developer, it is unlikely that you can anticipate the future well enough to plan for it, no matter your college GPA. This is something that is extremely difficult for bright but inexperienced developers to grasp, since it's all about not knowing what you don't know. Old hands may have recognized this weakness in your vision, and wisely encouraged you to just get into it and do your best.

Young developers may become obsessed with perfecting the design before they begin coding. They may be covering a fear of writing the code (performance anxiety), or may have coder's block (like writers block). They dally in design because there is no required work output. The young dev will probably respond angrily to the suggestion that they are "afraid" of anything. Maybe at the end of the project they'll realize that they were. The advice to just don't worry and get coding constitutes the only known cure for coder's block. An old hand may wisely offer this advice.

In the presence of harsh schedule constraints, your chances of getting the project done at all are limited. Plan too long, and no matter how good the plan is, you can't execute it in time, and you never get to market. Start hacking away from the start, and maybe you'll get lucky and be right the first time. You deliver the product miraculously. Or, maybe you're not so lucky, and deliver a half-baked piece of slag but it gets into the market on time and you learn something. Or maybe you fail. But "maybe you fail" is still better odds than "never got to market" because you planned too long. The key understanding is that your chances are limited from the start, so you lose nothing by hacking. Your manager may know there's little chance of success, and assigned a junior resource just as a learning exercise. We learn better from failure than from success. Have you perhaps been asking, "When can I have a whole project?"

It takes a pretty introspective and ego-free developer to see their own imperfections, so meditate awhile before reading the rest of this, lest you give yourself excuses to overlook your own weaknesses...

Not every developer is particularly good at analysis, planning, and other tasks that require thought. Thought is hard and icky. It requires a kind of mental sweat that leaves you uncomfortable and wrung out after a days work. It's just not as fun as getting into flow-state with your two cans of Monster and your rock turned up loud and coding, coding, coding. Developers who don't like to think will resist the notion that planning is a good idea. They recommend dev methodologies that don't require up-front planning. They like companies and managers that don't emphasize planning. They gravitate to jobs where the cost of not planning is not too high. They value all night coding sessions and getting that hotfix out to customers whose whole business is down because of a bug. (And never mind that delivering broken code to a customer ought to be a capital crime).

Certain developers have even realized that getting something working well enough to demo means that making it work completely and under all circumstances can be deferred, and maybe even pushed off onto another developer, while they receive kudos for "getting the job done" initially.

There are managers who cannot themselves spot a trend until it is already breaking on facebook. Instead of finding a job managing a discount tire store, these managers make it your problem that they need the code running by Friday. They don't want to hear that you need to design the API or test whether your algorithm is scalable. This is just tech mumbo-jumbo to them. They will encourage you to code because it's all they understood about software back when they were writing perl scripts to help customers transfer their files. (They had the title 'software engineer' in their first sales job. Who knew software was going to be so boring and hard?)

Your code is your visit card. If you write messy code, what tell you about yourself to the other people? Just think of that. Every time we find in office a really bad fragment of code, we ask ourselves, who have written it and how on hell was he passed through the university?

You are becoming what you code

Your code is your program for life.

A programmer writing bad code is like a ballet dancer dancing in striptease club

Some people don't care dancing in striptease club. But if they are tallented dancers, they are wasting their skills. If you are poor dancer but have nice legs, you can strip for many.

Finally, you should read Gogol's novelle 'The Portrait', and you should be warned by the story of the main character. You friend is similar to the man from the portrait. He is luring you with money, but you'll pay the high price for it.

I didn't ask for people to make personal comments about my mentor, I asked where the boundaries where with regards to over thinking design patterns. "Luring you with money" is a stupid irrelevant assumption, and in actual fact hes not the one paying me.
–
sf13579Jun 8 '13 at 17:34

4

Judging someone's intelligence based on one fragment is ludicrous. There isn't a developer alive that doesn't have their name on at least one piece of messy code.
–
Brian GreenJun 27 '13 at 19:59