views:

1960

answers:

17

We all know that programming patterns are excellent ways to provide a repeatable design amongst each other. While most people only use a few, choosing the right pattern for the right scenario is of utmost importance.

What are the three most vital patterns you believe any programmer should know and understand in their journey, and why do you believe these have the most impact on solid design and architecture?

+8  A: 

The major ones are of course the Factory Pattern. But one that is not listed in books is IOC - Inversion Of Control. There are many out there, autofac, spring.net, castle. I use castle windsor.

You should always start your designs with commonality and variability analysis first. Encapsulate what changes.

To be fair, all the design patterns are important, and I don't have any favouries, and neither should you. The factory is key to any good design as you should always separate the 'creating' from the 'using'.

Once you've got your commonality and variability analysis done, the design patterns will fall into place.

Can I suggest you read 2 very good books:

Simon Hughes
Thanks for the references, after having a look at "Head First design patterns" I bought it as a PDF. Interesting and entertaining read so far!
Renaud Bompuis
I'm reading HF Design Pattern at the moment. It might look goofy, but it is remarkably clear. +1
Abizern
IOC is just a concept, not a pattern. It is actually mentioned as the root of many patterns in the GOF book.
Null303
+3  A: 

It's hard to pick only 3!

I feel that the most important design patterns are those that promote decoupling and extensibility as these are often the areas that are hardest to understand as a young developer and so important for communicating ideas as a senior developer.

So, here's my 3:

Abstract Factory - to allow abstract things to remain abstract in the eyes of the consumer.

Registration - to allow for extension at runtime, say, through plugins (your Registry may be an Abstract Factory!)

Observer Pattern - I hate the Observer Pattern with a vengence. It is the source of sooooo many bugs when not implemented appropriately. So, this is in my top 3, not because I love it, but because you need to understand it so well that you don't abuse it and you know how to diagnose it's abuse.

And although not a design pattern, I would say that you must be intimate with the open/closed principal.

Daniel Paull
+6  A: 

Model-View-Controller -- should be considered for any app with a GUI, though there are other patterns that may work in certain circumstances.

Factory/Abstract Factory -- allows classes to create dependencies as needed rather than having to keep them around for the life of the object

Inversion of Control/Dependency Injection -- reduces coupling between classes and allows for much easier unit testing via mocking

tvanfosson
IOC and DI, is a Factory :P
dbones
There is a lot of overlap between many different patterns
1800 INFORMATION
@dbones, IoC _frameworks_ use factories to create the dependent objects. DI/IoC simply means injecting the dependency from outside the class. It can be done with out using an IoC framework.
tvanfosson
IOC is actually behind many patterns, it is more a technique than a pattern.
Null303
+1  A: 

Maybe not the most important but most common:

  1. Factory pattern
  2. MVC (and variations)
  3. Observer pattern
Pop Catalin
+1  A: 

iterator pattern, although it's built in to so many languages, and used so ubiquitously that perhaps most don't even think of it as a pattern

Dependency injection.

Factory/Abstract Factory

Charles Bretana
If "pattern" equals "refined method for working around language limitations" then "built in to a language" means "pattern no longer required".
Jay Bazuzi
Patterns are only that, they are not implementations.. When a particular implementation of a pattern is built-in does it not mean it is no-longer required... it means it's only required when you want something other than the built-in implementation
Charles Bretana
A: 

A few have already said Inversion of Control, but I want to focus on the Dependency Injection (DI) part of IoC. Dependency Injection is paramount for decoupled and testable designs. The number ONE pattern.

The next is Composed Method. Is harder to describe, but from the C2 wiki: Divide your program into methods that perform one identifiable task. Keep all of the operations in a method at the same level of abstraction. This will naturally result in programs with many small methods, each a few lines long. A strong SECOND.

The Observer pattern is also important to get decoupled and reusable components/designs.

Bent André Solheim
I would have to say that IoC and Dependency Injection are patterns in the wrong direction. Yes, they decouple code and allow for the insertion of test harnesses, but aside from that they're really not beneficial and make code very complicated and unnatural.
chaiguy
@chaiguy1337 - I'd like you to clarify why you think IoC and DI are "in the wrong direction". They promote decoupling and reuse. Factories can perform the DI to express domain specific cases, making it very easy to extend generic components into new domains/application. It's all good.
Daniel Paull
Ok I've been thinking about my comment and may be able to clarify my meaning. By "wrong direction" I meant for practical use. I think it's a valid theoretical study, but the DI I've been exposed to has been cumbersome and a lot of work, and I don't see it paying off.
chaiguy
Admittedly I am not that well versed in its theoretical backing so that is just my initial impression of it. I intend to research it further to either affirm or reject my position. At any rate I think it could be made a lot simpler.
chaiguy
I must agree with Daniel Paull; it's all good. Traditionally I have not been a big fan of annotations for DI. Recently, though, I have experimented with the Spring and JEE annotations in the Spring IoC container, and I it's now becoming very easy to use. Nearly no XML at the expence of nothing...
Bent André Solheim
+11  A: 

My most important pattern is the "don't get locked into following patterns" pattern.

Or would you call that an anti-pattern? :)

While I think patterns are a good teaching aid and generally help to give you new ways to approach solving a problem, I don't believe in the religious following of patterns above simply doing what feels right at the time. It's easy to put way more effort into rigidly following patterns than is saved by following them in the first place.

Of course if you work on a team, you have to respect your teammates and design proper reusable code, but just give it some thought first.

That said, I do still think there are some important patterns:

  1. Model/View I'm going to skip the typical third component in this pattern because nobody seems to know what they're talking about and there are at least three variations on it. The key point is that the visual representation of a piece of data should be separated from the operation (sometimes called business logic) of that data.

  2. Encapsulation I'm not sure this technically counts as a pattern (I haven't brushed up on them in a while), but it's a good rule to live by. Basically encapsulation means that you should only expose what is needed to use an object or control, and don't expose things that could end up creating unneeded dependencies. Typically, the fewer dependencies you have, the better.

  3. Composition over Inheritance I'm a strong believer that inheritance is on its way out, or perhaps a better way to say that is we are reaching a new level of abstraction that no longer needs inheritance. Composition involves the use of child objects to get the job done, rather than parent classes. So long as our data objects can properly communicate with each other (for example, be translated/transformed into different forms), inheritance is not really needed. Inheritance is useful on a lower level, when we define classes and interfaces, but composition is much simpler and more extensible, again because it involves fewer hard-wired dependencies. (WPF, for example, uses way too much inheritance, imo).

chaiguy
There were several answers that I would have loved to mark as correct, since this question can have a variety of answers. But, this one was really the most appropriate, balancing a few patterns with the pragmatic approach of not relying only on patterns.
Kevin Elliott
A: 
  1. Enumerable
  2. Factory
  3. MVC
plinth
+1  A: 

Hi

to put a spin on this

  • You Aren’t Going to Need It (YAGTNI), even Keep it simple (KIS)
  • Donot Repeat Yourself (DRY)
  • Last Responsible Moment (LRM)

have a look at Karls Foundations of programming page 8 and 9. for explinations on them. But if you follow these rules, you will most likely use the correct Design pattern.

To answer you question, its using the right pattern for the problem in hand. As some problems appear more often than others then you may find yourself using certain pattern more.

I find this site as a great link for patterns as it gives examples. Data and Object Factory. this will help you to choose the right pattern, if you buy the Ebook, it also says where MS used pattern in the .Net framework. which is really helpful.

HTH

Bones

dbones
+1  A: 
  1. Factory (The configurable flavor)

  2. Template Method

  3. Singleton/Static classes

etsuba
+1 to counter a pointless drive-by downvote
Steven A. Lowe
While singletons can make testing very difficult, done in a certain way they can be tested, however, I'm slowly starting to harbour the opinion that static classes are just not OOP, and are more trouble than the easy shortcut can be worth. Would love somebody to prove me wrong :-)
Grundlefleck
+2  A: 

There are no favourite patterns .. The question is pretty pointless because every pattern is good for one sort of problems, either you know them all, or you will end up making some mistakes other's have already done.

You should know as many patterns as you can, at least know about them and when to look them up.

Tigraine
+1  A: 
  1. input
  2. sequence
  3. output

these three patterns are pretty important.

even more important are

  1. assignment
  2. test
  3. branch

these three are sufficient for turing completeness

extremely common are

  1. how i meant to do it
  2. how i actually had to do it
  3. what i should have done

these come up in discussions quite frequently

Steven A. Lowe
+1  A: 

I am biased differently because I maintain a interactive CAD/CAM software for cutting machine.

1) Passive View found here

By making the actual forms a thin shells that interact with a UI Controller layer through a series of interfaces we were able to plug a big hole in automated testing. Our Q&A folks used a series of checklists that filled a 1" thick binder. Now it is a few dozen pages mostly focused on any new features or changes we made since the last release.

We used to have our software run only one type of cutting machine. When I converted over to a 32-bit architecture around 2000. I knew that some day we were going to expand the range of machines we support. So I developed the Passive View design in order to allow me to radically alter the software to allow customized version suited for new machine. This finally paid off two years ago when we quadrupled the number of types of machines we sold.

I was able to make several new types of control software in very little time. Because all of the software use the same core set of DLL (the model) bug fixes are easy to make. The automated tests ensured that the additions we made (new screen types) didn't impact the other UIs we add.

2) The Command Pattern

This was the biggest thunderbolt that hit me after reading Design Pattern by the Gang of Four. Finally a sane and easy design to allow for unlimited undo and redo. A great design to clearly separate out each type of action you have to do in response to events generated by the system or a user.

3) The Visitor Pattern

I know that this pattern is not looked at favorably by many but when you have to do a complex series of operations to create a specific cutting path the visitor pattern is the way to go. You can make the parameter very complex have all kind of subroutines, (looking sheepishly) have a few global variable (for that class only). All of it is packaged in one area where it is clear why everything is there.

So create a round flange all I have to is instantiate the flange visitor. Fill out the dozen or so properties and pass it to the visit method of a CuttingPathList and the correct number of flanges just appears.

RS Conley
+1 for command pattern. To me it makes actions so much more understandable, they help make your code more readable, and very testable.
Grundlefleck
+1  A: 

Short of memorizing the patterns by name and detail, I personally have more luck with Fowler's Bad Smells. And it's at least a little harder to get into an argument about them.

le dorfier
A: 

Not one vote for the Strategy pattern? No one writes code with multiple implementations of an interface and decides on the implementation at runtime?

Its up there with the Template Method and the Abstract Factory in my top three.

sal
A: 

I'm pretty sure these are not official "patterns" but:

1) For non-web UIs, I would probably like MVC except I'm spoiled by a personal discovery that reduces code by an order of magnitude, dynamic dialogs.

B) Code generation as a way of accomplishing DRY.

Gamma) Thinking about the problem as information flow, not as programming arcana like objects, methods, etc. etc.

Mike Dunlavey
A: 

I know this isn't really what you asked, but I'm going to list some anti-patterns.

I think these are the "most important" not because they're good, but because they're so pervasive and have such a big (negative) effect.

  • Spaghetti Code - incomprehensible, poorly structured, unmaintainable code.

  • Cargo Cult Programming - blindly duplicating what others have done without real understanding

  • Coding By Exception - adding code for new each special case as it's discovered

Clayton