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?

ashmish2
  • 301
  • 1
  • 4
  • 6
  • Maybe the answer to [this Stack Overflow question](http://stackoverflow.com/questions/3990899/design-patterns-criticism-sources) can help? – KooiInc Feb 18 '11 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. – Tulains Córdova Oct 31 '12 at 18:57
  • There is really excellent book to understand design patterns and object-oriented programming principles: [Head First Design Patterns](http://www.amazon.com/Head-First-Design-Patterns-Freeman/dp/0596007124/ref=sr_1_1?ie=UTF8&qid=1415726924&sr=8-1&keywords=head+first+design+patterns). May be this book even better than [GoF](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612/ref=sr_1_1?ie=UTF8&qid=1415726976&sr=8-1&keywords=gof) – Leonid Semyonov Nov 11 '14 at 17:29
  • https://bitbucket.org/waqqas-abdulkareem/notes/src/a6da2c21afab17aae56d7bfee62198620694758c/A%20Simple%20Guide%20on%20how%20to%20use%20design%20patterns.txt?at=master – W.K.S Jun 26 '15 at 09:40
  • Correction: design patterns do not help to make code _readable_. Who told you this? – user1451111 Aug 27 '18 at 03:44

15 Answers15

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.

jwenting
  • 9,783
  • 3
  • 28
  • 45
  • 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 '11 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. – Nemanja Trifunovic Feb 18 '11 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 '11 at 13:39
  • 17
    I think the point some people seem to be missing is that using patterns is *sometimes* the KISS solution – Geoffrey Bachelet Feb 18 '11 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 '11 at 15:09
  • Whenever you write some code with objects interacting you are using a design pattern. It may not be a published pattern or even a very good pattern - but it is a pattern. I think the 'pattern sceptics' who "actually use them all the time" will not be using out-of-the-box GOF patterns in their entirety and I think this is the danger that the OP seems to be heading towards in their seeming determination to apply design patterns whenever possible even if it's overkill. – El Ronnoco Feb 18 '11 at 15:19
  • 3
    @GrahamS: I *never* think it terms "will the X pattern apply here?". I just code my solution and if it fits a "design pattern" I use it to explain someone else what I did. In your example, I would just write an observer the same way I did before the GoF book was even published - I am sure many people would recognize it as the Observer pattern, but for me it is just a matter of communication. – Nemanja Trifunovic Feb 18 '11 at 17:24
  • @Geoffrey: I completely agree - especially with the *sometimes* part. – Nemanja Trifunovic Feb 18 '11 at 17:31
  • @GrahamS: What you'd want to see is, "Oh yes, I used a stack there." – Michael K Feb 18 '11 at 17:44
  • 1
    @Nemanja: *"In your example, I would just write an observer the same way I did before the GoF book was even published"* - you are aware of the pattern, when to use it and a standard implementation. Plus you would use it as shorthand to describe the code to other people. So basically you are using design patterns then - even if your own pride refuses to admit it. :) – GrahamS Feb 18 '11 at 17:50
  • 2
    @Michael: what I'd want is for them to recognise they need a stack and use the language/library implementation, not write their own buggy `MyLiFoDataTypeThing` from scratch and then later realise it is just a stack. So likewise I'd rather someone recognised an Observer pattern and used a standard library implementation, rather than write their own *ad hoc* version. – GrahamS Feb 18 '11 at 17:56
  • @GrahamS: I'm sorry, I may have misunderstood your point. That is indeed what should happen. However, some things are so basic (like arrays) that not knowing instinctively how they work is almost a sin. For instance, the Strategy pattern; that's not really something that can be implemented in a library, and it should be second nature to anyone who's worked with OO for a decent length of time. – Michael K Feb 18 '11 at 18:10
  • @Graham: I am not sure what you mean by "pride". I use design patterns for the purposes I find them to be useful. For instance, if someone asks me what C++ friend keyword is good for, I usually mention Memento. However, when I see a problem, I never attack it by thinking which design patterns I can apply here. Finally, I would never use the code samples from the GoF book - that's simply considered bad C++ nowdays. – Nemanja Trifunovic Feb 18 '11 at 18:19
  • @Graham - *"So basically you are using design patterns then - even if your own pride refuses to admit it. :)"* - that doesn't make any sense (and pride has nothing to do with it.) I mean, an observable/observer has been a well-known protocol (orthogonal but not the same as the producer/consumer protocol) for way long the idea of patterns started to be codified. What people did back then? Simply write your solution to the problem. Similarly correct solutions will share a common structure and consequences, and that's what a design pattern is, a documentation of such. – luis.espinal Feb 18 '11 at 21:11
  • 2
    @Graham - con't - and the problem is that people look at patterns as cookie cutters that people use mindlessly. In real life, most problems **do not** squarely fit into commonly established patterns, fitting instead into solutions that borrow (and alter) multiple patterns, many times **just barely**. And that's what the pattern-cookie-cutters fail to realize. You can't look "will the X pattern fits here", not unless you are dealing with the simplest of cases, or from a very high level architectural view. In most complex cases, that's simply **premature** structural optimization. – luis.espinal Feb 18 '11 at 21:18
  • 1
    @luis.espinal: as I said at the start, forcing code into a pattern is bad, so is treating patterns as cookie cutters or magic hammers. But, perhaps because of these bad practises, there are a people here trying to distance themselves by claiming they *"don't use design patterns"* when they clearly do. You can call it a *"protocol"* if you like, but if you use your experience to recognise a design situation you've seen before, apply a solution you've used before, and refer to your approach by a name that your team understand then that *is* using a design pattern. Even if it isn't in GoF! – GrahamS Feb 18 '11 at 23:52
  • 1
    @GrahamS - No no no. You got to read the posts you reply to. **You** seem to be missing the point. This isn't about how we call things (design patterns or protocols.) And I've not seen any of the people you are discussing with saying (as quote you) that they *don't use design patterns*. People are arguing **against** a design-pattern first mentality, just as people before we calling against a protocol-first mentality. – luis.espinal Feb 21 '11 at 14:14
  • 1
    @GrahamS - con't - The issue that seems to occur here is that **you** are not convinced of *code-first-then-refactor-into-patterns*, a practice that **1)** is tried and true (from even before Alexander's concepts of patterns started being considered in software), and **2)** can also be open to abuse (just like anything else.) **You** are not convinced despite time-tested evidence, and that is fine. What is not fine is that you assume that those that disagree with you are of the position of *not using design patterns* (as stated in your last post.) The later does not follow from the former. – luis.espinal Feb 21 '11 at 14:23
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.

David
  • 1,560
  • 9
  • 16
  • 14
    +1 *It's the job that must be identified and understood before the tool can be chosen* - Zen :) – El Ronnoco Feb 18 '11 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 –  Feb 18 '11 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. –  Feb 18 '11 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 '11 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.

GrahamS
  • 191
  • 1
  • 5
  • 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 '11 at 11:41
  • 1
    @El Ronnoco: Wasn't that the original reason for introducing design patterns? –  Feb 18 '11 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 '11 at 12:30
  • @El Ronnoco: I didn't mean to imply that they are only used verbally. They could equally be used in design documents, class/object names, or comments in the code. The point is that design patterns are primarily a communication tool and they are successful when they enhance understanding within the team. – GrahamS Feb 18 '11 at 13:14
  • After attending some design pattern conferences, I would say they were verbal shorthand at first. Then they evolved to a solution to a problem in a specific context with specific consequences. – S.Lott Feb 18 '11 at 14:41
  • @S.Lott I don't think you can say they were verbal shorthand at first, because then you raise the question of *verbal shorthand for what?* You can't have the descriptor with nothing to describe. Fair enough, their primary *use* might be as a verbal shorthand. But if their primary *use* is a verbal shorthand then that doesn't make them much good for actually solving problems :) – El Ronnoco Feb 18 '11 at 15:15
  • 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 '11 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"* – Denilson Sá Maia Feb 18 '11 at 15:47
  • @S.Lott I think don't think the OP is talking about "good, but informal ideas". I think they are talking about really quite rigid class structures as set out in many design-pattern books. – El Ronnoco Feb 18 '11 at 16:02
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/

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 :)

El Ronnoco
  • 180
  • 4
  • 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 '11 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

sinek
  • 131
  • 2
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.

bdutta74
  • 139
  • 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 '11 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 '11 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. –  Feb 18 '11 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.)

Macke
  • 2,576
  • 16
  • 16
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

Augusto
  • 992
  • 9
  • 16
  • 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 '11 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 '11 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.

Puce
  • 121
  • 3
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.

Spudley
  • 281
  • 1
  • 2
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

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.

dierre
  • 211
  • 2
  • 6
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.