57

In a previous question of mine on Stack Overflow, FredOverflow mentioned in the comments:

Note that patterns do not magically improve the quality of your code.

and

Any measure of quality you can imagine. Patterns are not a panacea. I once wrote a Tetris game with about 100 classes that incorporated all the patterns I knew at the time. Why use a simple if/else if you can use a pattern? OO is good, and patterns are even better, right? No, it was a terrible, over-engineered piece of crap.

I am quite confused by these comments: I know design patterns help to make code reusable and readable, but when should I use use design patterns and perhaps more importantly, when should I avoid getting carried away with them?

5
  • Maybe the answer to this Stack Overflow question can help?
    – KooiInc
    Feb 18, 2011 at 11:25
  • 5
    When you plug your TV set to a socket in the wall, instead of peeling off the cables and connecting them to two hot wires sticking out of the wall, you are using a pattern. Using patterns is easier than reinventing the wheel. It has always been easier to use an existing wheel than invent one from scratch. Oct 31, 2012 at 18:57
  • There is really excellent book to understand design patterns and object-oriented programming principles: Head First Design Patterns. May be this book even better than GoF Nov 11, 2014 at 17:29
  • Correction: design patterns do not help to make code readable. Who told you this? Aug 27, 2018 at 3:44

15 Answers 15

100

KISS first, patterns later, maybe much later. A pattern is a state of mind, mostly. Don't ever try to force your code into a specific pattern, rather notice which patterns start to crystalise out of your code and help them along a bit.

Deciding "ok, I'm going to write a program that does X using pattern Y" is a recipe for disaster. It might work for hello world class programs fit for demonstrating the code constructs for patterns, but not much more.

18
  • 19
    While I agree that code should never be "forced" into patterns, I disagree that code should be written first and Design Patterns applied as an afterthought. A good working knowledge of the patterns will actually help to KISS, as it saves inventing your own homebrew (probably broken) solutions to well-known problems. To me it is analogous to abstract data types: every coder should know what a stack, list and queue are and recognise when it is appropriate to use them - I wouldn't expect them to write code first and then say "Oh I could have just used a Stack there."
    – GrahamS
    Feb 18, 2011 at 12:20
  • 8
    @GrahamS - there is actually a nice book "Refactoring to Patterns" which shows how to write code first and refactor it into patterns later if it makes sense. Feb 18, 2011 at 12:59
  • 6
    @Namanja: I'm just not convinced that approach makes sense. For example, say I want to write an object that has a state and other objects that may be interested when that state changes. A coder that knows patterns will immediately start thinking: "Does the Observer pattern fit well here?". If it does then they have a well-known implementation and probably supporting library classes to use. Meanwhile Mr KISS Approach will still be handcrafting a bespoke design that probably couples all the classes together and leaves them in a tight tangle that is difficult to unit test later.
    – GrahamS
    Feb 18, 2011 at 13:39
  • 17
    I think the point some people seem to be missing is that using patterns is sometimes the KISS solution Feb 18, 2011 at 14:53
  • 4
    @Geoffrey: yes, my point exactly, well said. Also many pattern sceptics actually use them all the time, but just don't give them names.
    – GrahamS
    Feb 18, 2011 at 15:09
53

I think the main concern is that people often have a tendency to abuse design patterns. They learn a few, see the usefulness of them, and without realizing it turn those few patterns into a kind of golden hammer which they then apply to everything.

The key isn't necessarily to learn the patterns themselves. The key is to learn to identify the scenarios and problems which the patterns are meant to address. Then applying the pattern is simply a matter of using the right tool for the job. It's the job that must be identified and understood before the tool can be chosen.

And sometimes it's an odd setup and there is no cut-and-dry pattern to solve it right out of the box. At that point more attention needs to be given to the problem rather than the solution. Break it up into component problems, identify areas of the problem which share common traits with problems addressed by known patterns, adjust the patterns to fit the problem, etc.

4
  • 14
    +1 It's the job that must be identified and understood before the tool can be chosen - Zen :)
    – El Ronnoco
    Feb 18, 2011 at 11:31
  • 2
    +1 developer should not just know the patterns, he must understood them and use some aspects or mix of patterns to produce good solution
    – endryha
    Feb 18, 2011 at 11:40
  • 2
    +1. How the pattern is applied is also rather important, even when it does elegantly solve the problem. A lot of people tend to resort to a lot of LCD OOP techniques (following things like Java examples too closely for applying the same pattern in C++) when a design pattern does not strictly have to be implemented that way.
    – stinky472
    Feb 18, 2011 at 16:03
  • 1
    @user374980: Agreed. The patterns themselves are essentially language-agnostic, but different languages will have different details on the best way to implement them. Simply porting an implementation from C# to, say, Ruby may be ill-advised. Attempting the same to Lisp is downright silly :)
    – David
    Feb 18, 2011 at 16:06
25

A design pattern works best when it is used as a common language in your team.

By that I mean, you can say something like "this class is a Singleton that implements our IHairyWidget Abstract Factory" and everyone in your team understands what that means without having to go into detailed explanations.

Where Design Patterns fail is when the team doesn't understand them, or when they are overused so much that they stop making the design clearer and instead make it harder to understand what is really going on.

9
  • 4
    Good point for the benefits of using them as verbal shorthand for complex concepts. It's making sure you're using the correct complex concept in the first place that is key :)
    – El Ronnoco
    Feb 18, 2011 at 11:41
  • 1
    @El Ronnoco: Wasn't that the original reason for introducing design patterns?
    – 7vies
    Feb 18, 2011 at 11:55
  • @7vies I don't think design patterns were introduced to be verbal shorthand. I think they have become verbal shorthand for those familiar with them.
    – El Ronnoco
    Feb 18, 2011 at 12:30
  • 1
    @El Ronnoco: "you raise the question of verbal shorthand for what?" Not really. It's verbal shorthand for a good, but informal idea. Later, it got formalized. Things (like the idea of a design pattern, as well as the patterns themselves) proceed through a series of refinements from good idea to more formalized idea. We had design patterns long before we had the concept of "design pattern".
    – S.Lott
    Feb 18, 2011 at 15:18
  • 1
    +1 "or when they are overused so much that they stop making the design clearer and instead make it harder to understand" Feb 18, 2011 at 15:47
14

maybe a bit off topic, but I think it covers your question too: I would suggest you a good book Refactoring to Patterns:

This book introduces the theory and practice of pattern-directed refactorings: sequences of low-level refactorings that allow designers to safely move designs to, towards, or away from pattern implementations. Using code from real-world projects, Kerievsky documents the thinking and steps underlying over two dozen pattern-based design transformations. Along the way he offers insights into pattern differences and how to implement patterns in the simplest possible ways.

you will find examples when design patterns are good to use, as well as when you need to go away form them, not to make application overcomplicated. And yes, the main idea is to keep everything as simple as possible.

Good answer/advice to your question was in article Do You Recognise the 4 Early Warning Signs of Design Pattern Abuse?, but I can't load it now, error 500. It is not big, so I just used google cache to get it:

Software design patterns can and do lead to over-engineering

Over-engineering is the process of over complicating something. In the case of programming, making your code more complex and possibly more flexible than it needs to be. More specifically, implementing complex software design patterns on simple problems.

1. Start simple not complex

How does this happen? Usually you program in extra functionality that you anticipate will be used or prove to be useful later. But what happens if this need never materialises? In most cases, the cruft gets left there. It doesn’t get removed. So the software system continues to grow in size and complexity with all these features that aren’t ever being used.

2. Be wary of the signs

This is perhaps different for everyone but I suspect in most cases, it isn’t really a conscious effort. But rather, it is something brought about by the fear of being stuck with an awkward, inelegant, inappropriate or simply put, bad design; being stuck with something that just isn’t flexible enough. Ironically, if you get to the point of over engineering or over applying patterns you are right back where you started.

Software design patterns appeal to programmers or developers because they allow them to naturally express and create beautiful architectures. It's a part of enjoying creative programming.

3. Consider refactoring to a pattern rather than starting from one

What might be a good way to avoid this design pattern abuse? Consider refactoring to a pattern rather than starting from one. Don’t start out trying to force a pattern into your design. Chances are your design could be much simpler without it. If you do find at a later stage that your design truly could benefit from a structured pattern, then refactor to allow for it. When you design, solve the problem in the simplest way possible. Simple light weight software is always a good thing. There are better ways of avoiding the under-engineered alternative where you get stuck with a design or solution that just isn’t flexible enough or doesn’t suit the problem.

4. Don’t force yourself to get it right the first time

Forcing software design patterns or structures into design just isn't the answer, that's just bad design. But prototyping or building an initial build0 (proof of concept build before production on the actual product begins) can help avoid this and the problem of over-engineering. Because you don't feel like you have to get it perfectly right the first time.

Original URL (now dead): http://codelines.net.au/article/do-you-recognise-the-4-early-warning-signs-of-design-pattern-abuse/

4
  • +1. A great book, although the title sounds like random collection of buzzwords. Feb 18, 2011 at 13:01
  • Random collection? It is only 3 words long. Feb 18, 2011 at 18:02
  • +1 Great points! even the "Don’t force yourself to get it right the first time". I can feel that! Jul 11, 2011 at 12:36
  • Who wrote the big quote? I think it's very well put.
    – Gruber
    May 23, 2017 at 10:25
9

when to stop doing everything using patterns ?

The question is when did you start doing everything using patterns? Not all solutions fit neatly into an existing design pattern and adopting a pattern may mean that you muddy the cleanness of your solution. You may find that rather than the design pattern solving your problem you generate a further problem by trying to force your solution to fit a design pattern.

Obviously, if you pick the correct design pattern for a particular scenario then you won't have a problem, however picking the correct one is easier said than done.

I have seen overuse of patterns in projects where they are really not necessary.

I think the key is - Try to keep your code clean, modular and readable and make sure your classes aren't tightly coupled. Eventually you may see that you have inadvertently used a variation on a standard design pattern. Perhaps you would have realised this at the very start of your project before you started coding. If you code like most people I know (including myself), then probably not :)

1
  • 3
    Hear! It's actually a bunch of guys noticing that "hey, it looks like we've been solving a lot of problems in the same way, lets publish that so people that have similar problems can peek at our solutions.". Then, all of a sudden, people thinks it's some kind of law. The expert knows when to ignore a rule of thumb, or even break a law...
    – KarlP
    Feb 18, 2011 at 15:01
5

Well, the most important thing is to know the problem that you're solving. Than you need to decide whether introducing some pattern would gain you some advantages over not using it (gain on performance, simplicity or whatever). Related questions: https://stackoverflow.com/questions/85272/how-do-you-know-when-to-use-design-patterns

4

The no. of design-patterns mentioned in the original / de-facto go-to text on the subject, i.e. GoF requires quite a bit of experience and often several re-reads, and brain-storming with competent colleagues to master. Post that stage, given a problem, given an architecture, often the most natural design-patterns come out in fairly obvious fashion. However, any attempt to force-fit design-pattern to problems, or map problems to design-patterns is fraught with danger, in which case it is best to consult experts, brain-storm a bit and take it as a learning experience. Unless you are quite comfortable with commonly used 10-odd design-patterns, this is going to stay a bit tricky, and AFAIK, there are no shortcuts.

I've come accross million SLOC C++ code projects with ample examples of force-fit design-patterns, so mistakes s.a. overuse aren't very uncommon.

3
  • Definitely agree with you, I've read the GoF book 3 times and each time I got a way deeper understanding of the patterns... which doesn't mean that now I understand them.
    – Augusto
    Feb 18, 2011 at 11:40
  • GoF is very dry and quite dense. Sad to say, but the "Head First Design Patterns" is a far better introduction to the subject (despite its "For Dummies" aesthetic).
    – GrahamS
    Feb 18, 2011 at 11:45
  • 1
    @Augusto. Thanks for the comment. @GrahamS, you assessment of GoF as "dry & dense" is something lot of folks (maybe majority) might agree with. However for many of us, it was pretty much the only thing we had, barring a small handful of other options... s.a. POSA. "HFDP" is definitely a lot lighter newer book, and having read it a little, I've to admit, it makes learning DP seem a lot easier.
    – icarus74
    Feb 18, 2011 at 13:27
4

It sort of goes like this with any topic that requires you to learn and apply rules:

  1. If you are a newbie, you need to follow the rules because you don't know better.
  2. If you are an amateur, you follow the roles because you know why you need them.
  3. If you are a professional, you work with the rules rather than against them, knowing well what to use where and when they don't apply.
  4. If you're an expert, you ignore the rules.
  5. If you've mastered your art, you prefer the rules since your code has to be seen by category 1-3 people too. :)

It's the same with martial arts, painting, writing, soccer, mechanics, race driving, etc etc...

As a #5 guy, you usually end up teaching the #1-#4 guys how to become the top, so it always applies, even in competitive contexts.

(How to Transcend and Ignore the Rules explains this in a general sense, but there are probably better essays out there.)

3

The rule is that there is no rule. Your experience (success more than failures) will tell you when to use them purely, when to adapt them or when not to use them at all.

There's a presentation by Dan North in which he talks a bit about learning and patterns

2
  • I meant design patterns cover a broad spectrum and you can solve almost all the trivial problems using that. So when we shouldn't be carried away by this
    – ashmish2
    Feb 18, 2011 at 11:29
  • I think the answer would be "when you're trying to design an MVC framework as a strategy, which uses flyweight controllers ..." I hope you get the idea :). I think the bottom line for me would be: Don't use a pattern that doesn't fit in the problem (with a small adaptation if it's necessary).
    – Augusto
    Feb 18, 2011 at 11:38
2

Keep everything as simple as possible. I you have to solve a problem however, you might want to use a design pattern however, rather than reinventing the wheel, as many design patterns provide solutions to common problems. But as I said: only use them when really needed.

2

Maybe use the KISS DRY SoC pattern (yeah, maybe it's not a pattern, but it sounds fun).

Keep It Simple, Stupid.
Don't Repeat Yourself.
Separation of Concerns.

I think these three points should be inspirational for any programmer.

1

The problem with "patterns" is that anything can be considered a pattern, and often is.

I had been developing code professionally for a long time before I first heard anyone talking about 'patterns', and I managed just fine for all those years. In fact, when I look back, a lot of the stuff I wrote actually followed some of the well known patterns, at least to some extent.

My point is that following any given pattern rigidly isn't really the answer. Learn about new patterns, but don't get yourself tied to them: They will change. Good coding practice today is not the same as good coding practice ten years ago, and no matter how clever today's programmers are, you can be sure that ten years into the future, things that are considered good practice today will have been superceded.

Off topic: On a personal note, I really hate the usage of the word 'patterns' in this context. It reeks of unnecessary jargon.

0

Imho you'll just know it. I mean I even used a design pattern before I knew the definition of design pattern. It's just good coding. Sometime you'll be able to recognize it while writing the project requiriments and sometime you have to refactor your code.

jwenting said KISS first, patterns later. I think patterns are a way to KISS a project because you can apply something you know it works and will spare your time in the future.

The only thing that could go wrong is that there many ways to implement a single design pattern, even in the same language, so you need to understand completely what is your problem.

0

The way you structure your code's logic should allow for a newcomer to that code to be able to interpret it and modify it. Having a pattern just because it's a best practice won't get you anywhere if you don't fully understand the context of how, whom and where that code is and could potentially be used.

The "Keep it simple" pattern is more of a common sense thing than a pattern and it has to be a part of a developer's thinking process when creating code. Assuming that everyone gets a particular pattern isn't necesarily correct as well. Ideally you want a pattern that can be read and identified without so much knowledge of it.

0

Well usually design patterns are used to explain the wider audience what your code really does. This way it makes it easier for people to understand what you are doing. One rarely uses it as a reference to come up with solutions, as a pattern can actually be implemented in many ways.

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