This question came from our site for professional and enthusiast programmers. Votes, comments, and answers are locked due to the question being closed here, but it may be eligible for editing and reopening on the site where it originated.

This question appears to be off-topic. The users who voted to close gave this specific reason:

"Questions seeking career or education advice are off topic on Programmers. They are only meaningful to the asker and do not generate lasting value for the broader programming community. Furthermore, in most cases, any answer is going to be a subjective opinion that may not take into account all the nuances of a (your) particular circumstance." – gnat, Jim G.

@Dominic - "learning about algorithms" isn't really clearly defined. Which algorithms? Just the classics, or including things like cache-oblivious? Cookbook or deep understanding? How much on adapting the basic building blocks (e.g. augmenting data structures)? Priorities vary and, with fallible student memories too, it's amazing how often you'll find someone who seems competent right up until he says "what is this binary heap of which you speak?".
–
Steve314Jun 15 '11 at 7:16

15

The so called "design patterns" are only useful when you've got enough experience to re-invent them on your own. Before that, an epic abuse is inevitable, so it is better to stay away from that patterns quite for a while.
–
SK-logicJun 15 '11 at 9:34

3

@SK-logic - I disagree. Although without a context of how to design software, patterns aren't that useful. A software design course that teaches how to identify and use patterns is a second year course at the university I attended.
–
Thomas Owens♦Jun 15 '11 at 11:58

Any time! Design patterns are fundamental in not only how we structure our programs but they affect the ways we actually think and discuss solutions. The earlier someone can get started with design patterns they faster they can become "fluent"

Algorithms are nice but let's face it, you can do ha helluva lot programming without ever having to implement an algorithm from scratch yourself. Knowing what algorithms are available and what they're appropriate for is a good first step for a junior programmer but I'd still say design patterns are far more important for daily work.

Algorithms tend to have far more programming "cred" then design patterns. Designing and learning sophisticated algorithms is the "cool" thing to do. In some areas you do need design and implement sophisticated algorithms but they're fewer then you think.

<rant>

I have a pet theory that algorithms vs design patterns is right-brain thinking vs left-brain thinking. Many programmers come mainly from the left-brain side of things with a deep interests in maths, science and engineering, it's very natural that they'd find algorithms more exciting. Heavy left-brain thinkers are typically stronger at a method level then overall architecture.

On the other hand we have the right-brain thinkers with a stronger aptitude for language, arts, and patterns. They might not be as strong on the method (algorithm) level but they're strong when it comes to overall architecture.

If you're going to be a good general programmer it's important that you master both left and right brain thinking

Since when this "design patterns" buzzwordy BS became "fundamental"?!? And, by the way, "design patterns" is the worst way of thinking on an architectural level, ever. Even worse than OOD.
–
SK-logicJun 15 '11 at 9:38

Algorithms

My personal opinion is that you should not dive into design patterns before accumulating some experience with programming in general first. To get design patters you need to have a first-hand experience of the problems they will help you solve (someone who has never needed a fire will find it hard to understand the usefulness of matches).

Algorithm (i.e., how to think in code) training is a good way to train in problem solving, and you need to have that experience in order to harness the power of design patterns.

From my very personal view: For 95% of all problems we can find excellent and performant algorithms (sorting, selecting, hashing, ...), so it's more productive to know when to use them (and which variant) then trying to reimplement the wheel.

Make them understand the basic patterns and why to use patterns. You'll have to tell them that class xy shall get notifications of state changes on class yz and they have to know, that you want them to implement an Observer Pattern and they'll have to be able to do it without further guidance.

If you have a very special algorithm, then you usually have some senior software engineer or an architect that will design the algorithm and hand it over for implementation.

One have to study algorithms in order to be able to design algorithms, to think algorithmically and to design an architecture of higer levels of abstraction. Not just for being able to re-implement quick sort over and over again. And patterns... Patterns are just a crap, nothing more. One capable of thinking on a decently abstract level won't ever need a collection of pre-cooked patterns.
–
SK-logicJun 15 '11 at 9:41

@SK-logic - most likely the new team members will not design algorithms in their new (first) job. Once you start looking into complex applications (with more then one or two classes) and want to get things done, you need patterns. I'd never accept or even pay a developer in my team who refuses to use patterns just because he thinks he doesn't need them because he smarter then the rest of us. Never.
–
Andreas_DJun 15 '11 at 11:46

as I said - learning how to design and analyse algorithms is a pre-requisite for learning how to design an architecture. Even if you won't ever implement a single algorithm in your life, you have to know how to do it in order to be able to reason about entities of a higer level of abstraction. There is no way around it. And, yes, you do not need that stupid GoF patterns for doing complex things. You need an ability to identify and invent patterns. Knowing specific patterns but lacking this ability most certainly will lead to a disaster. Just as well as any misuse of an OOD.
–
SK-logicJun 15 '11 at 12:24

The most important is to start building a team. Develop coding style that vocabulary that makes you understand each other. Then move to programming principles that will make your code maintainable (simple and clear). When you reach that point you will know their potential and you will be able to guide them according to their skills. They should know both algorithms and design patterns with emphasis to the one that they will need more. Large scale design requires patterns while specific problem solving requires algorithms. Whatever you do I insist in the creation of a real team. It is the method I use and it never failed yet.

If your company is producing custom line-of-business software, CMS/Website development, and related things, Design Patterns will be the most useful. I rarely have to implement anything close to the algorithms learned in school in my work life (but its good to know them, plus learning to implement them is extremely valuable in helping you break down everyday problems). Yes, teaching a junior programmer Design Patterns will most likely casue them to start overusing them, but if you are reviewing their code on a regular basis (you should be) then hopefully you'll be able to nip the worst problems in the bud before they become a real issue in your code base. Plus, the Design Patterns flow well into helping them write testable code and the SOLID principles that are foundational to maintainable code, which is what is really important.

Now, if you are implementing Financial Trading code, scientific code, logisitics routing code, Algorithms are probably more useful, as these fields are much more dependent on the basic Computer Science knowledge to be productive, unlike business code which feeds off more of the Software Engineering side of profession.

First you teach them how to program by making them understand what their code does and how to execute it in their head. You teach them a specific programming language with simple examples. This is analogous to basic vocabulary in a spoken language.

Next you teach them how to design. How to split things up into functions and composable units. Make them create lots and lots of interfaces and figure out which break and why and which don't. This is like grammar, it is a bit fuzzy and there are exceptions to almost any rule but you still need to get a general feel for what works and what doesn't.

Algorithms in most cases are solutions to very specific problems. "If you want insert and remove in O(1) use a list not an array." This can help you speed up your program and although it is sometimes necessary to get a useful program at all mostly it is an optimization. I enjoy algorithms but I almost never need them for my job as an application programmer. If you do, this site quickly helps you find what you need. ;)

Design patterns on the other hand are solutions to quite common problems. They are like proverbs: "Don't poop where you eat." You can analyze it and figure out a couple of reasons of why they may make sense but they are basically guidelines. Things that worked for people. They can be quite useful in providing a common vocabulary for ideas and giving you starting points for piecing together your designs.

So if I had to pick I would probably go with design patterns. :)
They are guidelines for what is, to me, the harder and more influential part of programming: Design, Architecture...
I say more influential because if you have decent modularity changing an algorithm is much easier than changing the architecture.

Build a smart team that gets things done

Quoting one of Joel's books a little, I would advice to have the new team members solve a task together, to build kind of tool that you may need internally anyway. This is an achieveable task and if it really goes wrong, the risk is limited.

After that, you do a post mortem review togehter and discuss all the things where they are strong and the things where there are weaknesses. Analyze and develop an action plan from it, what they need to learn now, and later.

Follow-up regularly to make sure they are making progress and to adjust the course of action.