139

I had a discussion with one of our senior developers who's been in the business for 20 years. He's pretty well known in Ontario for a blog he writes.

The strange thing is what he told me: he said that there is a piece of code that is a nightmare to work with because it was written from a textbook, and doesn't account for the real world. Adding a new field to the UI/database/Data layer takes 2-3 hours to do, whereas in his code it takes 30 minutes.

The other thing too is that he avoids design patterns because most programmers don't understand them and they are not good from a maintenance perspective.

Then there's also the idea that most web developers in Canada prefer to have their data model inherit from the Data Layer classes, rather than keeping it isolated. I asked him, "Isn't it industry standard for the model to be separated from the data layer?" He said sometimes, but most people here prefer not to do that because it's too much work.

It sounds like his reasoning for not coding using best practices is because it's a maintenance nightmare, few of our employees understand it (besides myself), and it's slow to work with if you need to push out new features or fields in a few days' time.

It's so strange hearing an opinion like this, considering that Stack Overflow mostly encourages people to follow industry standards. Is the problem that we are constantly forced to churn out new fields and features in a matter of days, that it's not possible to deduce a solid pattern that is flexible enough? That seems to be the gist of what I understand from this.

What do you make of these statements?

30
  • 48
  • 70
    Personally I'm nervous of anything refered to as "best practice" (without justification) because it usually means "I don't know why this is a good idea but I want you to do it anyway; end of discussion" Aug 30, 2016 at 21:31
  • 35
    industry standard , design pattern , and best practices are just terms for "Things that someone said work better on their context so it sohuld on yours too. probably. maybe"® . your senior dev's right.
    – CptEric
    Aug 31, 2016 at 6:37
  • 86
    This has nothing to do with Agile. Aug 31, 2016 at 8:53
  • 71
    "senior mvc developer" "design patterns are bad" the cognitive dissonance
    – Dan
    Aug 31, 2016 at 11:44

13 Answers 13

245

These are the words of someone who has found success and ignores people that try to tell him what to do in pattern jargon that he doesn't understand.

Design patterns and best practices are not the same thing. Some people think they are and drive people who know what they're doing nuts. Even if they don't know the proper name for what they are doing.

Design patterns existed before they had names. We gave them names to make talking about them easier. A pattern having a name doesn't make it a good thing. It makes it a recognizable thing.

This guy is likely using patterns neither one of you ever heard of. That's fine, until you need to talk to him about how something is done. He's either going to have to learn how to talk to you or you're going to have to learn how to talk to him. Has nothing to do with who is "right."

14
  • 13
    Agreed, with the caveat that, when most people use the term "design patterns" nowadays, they're usually referring to the Gang of Four. Aug 30, 2016 at 19:39
  • 35
    Right and I like using English, it makes sense to me. Don't know why it's taking French people so long to adopt it. Till they do I'm going to learn a bit about this metric system I keep hearing about. Aug 30, 2016 at 21:00
  • 6
    It might not be that he doesn't understand, it might also be that he does understand but he knows that not everything applies in all situations. Aug 30, 2016 at 21:15
  • 150
    "A pattern having a name doesn't make it a good thing. It makes it a recognizable thing." Oh my god this is the best summary of the problem I've ever heard :D Aug 31, 2016 at 8:53
  • 7
    @JanDoggen They're called (anti-)patterns because they are also common patterns in software development (some of which are design-related patterns).
    – JAB
    Aug 31, 2016 at 17:20
96

Many design patterns, of the kind that you and your friend are describing, are really just workarounds for deficiencies in programming languages. Use a more expressive programming language, and most of the need for these design patterns disappears.

Because good design patterns are required to cater to many possible usage scenarios, they tend to be over-engineered. Over-engineered code has a cost: you have to read it, understand what it does, and understand how it works within the context of the entire software system. Consequently, as with any other software development technique, you have to evaluate the technique against the cost of using the technique, and decide if the benefits exceed the cost.

All other things being equal, less code is always better. I've been through layered architectures where you literally have to make three to six hops through multiple projects to find any code that is interesting, which is to say, code that actually accomplishes something other than adding overhead.

Well-known software patterns are supposed to give you a common vocabulary by which you can communicate design strategies. Unfortunately, many software developers don't understand the software pattern vocabulary well enough to properly apply it to their programming problems. Inexperienced developers see these patterns as being within the domain of experts; they want to be seen as experts, and so they try to learn and apply the patterns too early, before they are ready. What they really should do instead is focus on learning the fundamentals of programming first, and then attempt to solve the problem that each pattern solves themselves. If they do this, they will be in a much better position to understand and apply the patterns correctly.

21
  • 19
    Well, that's a different problem than the one you're describing in your question. The shop I work at now is living proof that you can be agile and still have very clean, lean code that is easy to maintain, but it is not the usual enterprise, multi-layered stuff you see in most Java shops, and it's fairly "non-standard" in its approach. We don't have a year to build apps the "enterprise" way. Aug 30, 2016 at 20:21
  • 34
    @Igneous01: Note that what a professor who has never had any real-world experience considers "good" could vary radically from what a business trying to make money considers "good." Aug 30, 2016 at 20:58
  • 8
    "Unfortunately, many software developers don't understand the software pattern vocabulary well enough to properly apply it to their programming problems." This is me in a nutshell. =) The few I have seen the names of, I have an extremely difficult time spotting a real implementation of them. I probably have blocks of code I've written that could be classified as implementing patterns, but I sure couldn't tell you which ones. I've come to think that the patterns are much less important than the code actually being decipherable and requirements changes only affecting a few places of code.
    – jpmc26
    Aug 31, 2016 at 1:54
  • 35
    While I'll pedantically take issue with "less code is always better" because I know it leads to code that looks like brainfuck, I will enthusiasicly agree with the "pattern vacabulary" point. Don't complain that my code is crap just because you can't find it in your textbook. There are plenty of perfectly good reasons to call my code crap, but that isn't one of them. Aug 31, 2016 at 2:04
  • 23
    "code that actually accomplishes something other than adding overhead" -- I thought the goal of enterprise software was that there should be no code that actually accomplishes anything. Any actual behaviour that the software might have, should either be an emergent property of the layered design, or else should be table-driven from business rules that the code treats as data. I'm only 50% joking. Aug 31, 2016 at 8:32
86

Stackoverflow.SE and Programmers.SE mostly encourage people to follow best practices like SOLID, not industry standards. And believe it or not, the de facto industry standard is often the "big ball of mud" architecture - seriously.

But to answer your question directly: the problem with design patterns is a similar one as with inheritance - lots of mediocre devs overuse them, which has a certain risk of creating overengineered, hard to maintain code. But the answer to this is surely not to avoid or forbid the use of design patterns (or inheritance) completely, the answer is learning to use these tools in situations where they make sense, and only there. And this is fully independent from working "agile" or not.

2
  • I think the specificity of your statement "the problem with design patterns is a similar one as with inheritance - lots of mediocre devs overuse them" is unnecessary... with all aspects of coding, a developer not educated in the proper use of something may and often will misuse it, and write sub-optimal code. This could be considered an axiom of development in general. Sep 6, 2016 at 14:49
  • 1
    @JeremyHolovacs: not exactly. The problem I see is that even educated developers overuse them. I have seen too often solutions where experienced devs tried to shoehorn a problem into a pattern which did "somehow" fit, but not well.
    – Doc Brown
    Sep 8, 2016 at 5:47
45
  1. Design patterns are just names used to communicate ideas. I often found myself doing things which later I found that have a name. Thus, there is no "design pattern way" as opposed to a "non-design pattern way".

  2. Design patterns are guidelines. As everything, each of them has advantages and disadvantages. The key is not to learn the pattern and apply it where it fits but rather to understand the idea of the pattern, the advantages and disadvantages it has and use it to get inspiration for the solution to your problem.

  3. Every best practice and guideline can be ignored if there is a good enough reason. Valid reasons include development time and expectations from the application. For example, I'm aware that it's bad to hardcode values (stupid example) but for a proof of concept, the advantages might outweigh the costs (in this case, mostly development time). However, if a decision like this is made, it might backfire and at some point a refactoring might be required.

1
  • 5
    RE: number 1, yep, been there - I invented the template pattern. I just didn't do it first. Or anything like first. Aug 31, 2016 at 15:24
30

To add another metaphor to the soup, design patterns are Clippy the Microsoft Office helper. "You seem to be doing the same thing to a whole bunch of stuff. Can I help you with that by offering you Iterator or Visitor?"

A good write-up of those patterns will indicate when it's useful to do something the same way it's been done many times before, what mistakes you'll make the first time you try it, and what common ways have been found to avoid those mistakes. So you read the design pattern (or review it from memory) and then you get on with your work. What you can't do, is get by only using Clippy and wizards.

Where inexperienced people can go wrong and write code that doesn't take account of reality, is when they think their list of design patterns is a complete list of all possible approaches to solving problems in software, and try to design code by linking together design patterns until it's finished. Another poor tactic observed in the wild is to shoe-horn a design pattern into a situation it's not really suited for, on the basis that the design pattern "is best practice". No, it may or may not be best practice for the class of problem it actually solves, but it is certainly not best practice for problems that it fails to solve, or for problems that it solves only by introducing needless complexity when there's a simpler solution.

Of course it's also possible for someone to avoid a pattern on the basis that YAGNI, then realise they do need it and grope towards the normal solution. This is usually (but not always) worse than realising the requirement from the beginning, and is why even in agile development it's frustrating when totally predictable requirements aren't discovered early. I cannot have been the only C++ programmer who was highly amused that Java initially rejected generic containers as needlessly complex, then bolted them back on later.

So it's almost certainly a mistake to avoid writing an Iterator on principle because you prefer to avoid design patterns.

Adding a new field to the UI/database/Data layer takes 2-3 hours to do, where as in his code it takes 30 minutes.

You can't really argue with that: by this metric his design is far better than the other one. Whether that's because he avoided design patterns is questionable though, I think it's more likely because he considered the right "real-world" issues when designing it, and with the benefit of experience is better at his job than someone armed only with a textbook and high ideals.

So he recognised that any pattern which requires you to touch a lot of different points in the code to add a field is a bad pattern for the job, "make it easy to add fields", and he didn't use those patterns. Layered architectures indeed can suffer in that respect, and it is wrong to use design patterns without appreciating their disadvantages.

As against that, how long does it take to write a new UI in his design, and how long does it take in a layered architecture? If the project called for him to constantly build and deploy new UIs over a fixed data model, instead of constantly adding fields, hopefully he'd have designed for that instead. Or as well. But for all its benefits, saying "we're doing agile" sadly does not mean you'll never have to make another trade-off!

Selecting from a menu of design patterns certainly can stop you thinking about the most important concerns. But recognising when you're writing a Visitor, and documenting or naming it "Visitor" to help readers get it quickly, doesn't much get in the way of anything. Writing "this is a Visitor" instead of documenting it properly is a terrible mistake for the reason your senior dev gives -- programmers won't understand it. Even programmers who know what a Visitor is need more information than just, "this is a Visitor".

3
  • 5
    "design patterns are Clippy the Microsoft Office helper" I'm going to have nightmares tonight. Sep 1, 2016 at 11:40
  • "Where inexperienced people can go wrong [is when they] try to design code by linking together design patterns until it's finished." Hear hear. I wish I had multiple upvotes to give. :) Sep 4, 2016 at 18:37
  • I also wish I had multiple upvotes for the final paragraph. Design patterns are the vocabulary of programming: you'll be a better and clearer writer if you have a large vocabulary. I can tell a Factory from a Builder when I see them, but I didn't get that from reading books on design patterns, any more than I learned how to tell a crag from a bluff by reading an English dictionary. Sep 4, 2016 at 18:38
20

Your colleague seems to suffer from the NIH syndrome ("Not Invented Here").

It's perfectly plausible that his code makes it easier to add new fields: I'm also much faster to update my own code than the code written by other guys. But this short-term speed doesn't say anything about the maintainability and portability of the code. I'll give him the benefit of the doubt: The existing code might indeed be badly structured if it has followed a textbook badly or followed a good recipe in the wrong context.

Avoiding design patterns is really surprising. In my last 30 years of coding and managing coders, design patterns helped to put words on things that were done instinctively, helping so to understand more quickly the intent, the advantages, inconveniences, risk, opportunities and related patterns. Design patterns proved to be real accelerators for mastering complexity!

  • Perhaps your colleague is really much more intelligent than most of us and he can afford the overhead of reinventing patterns without noticeable productivity decrease?

  • The arguments that "programmers don't understand design patterns" sounds like "I can't really explain what I'm doing". Or "I don't want to argue about my own design". I really think that patternization could leverage overall understanding, and it could allow less senior colleagues to share valuable opinions. But maybe your senior colleague wants to avoid just that.

Layered approaches have proven to be superior to other architectures in most enterprise applications. World-class leading packages are structured around this idea and outperform artisanal architectures by orders of magnitude. Martin Fowler presents this approach in his excellent book on "Patterns of enterprise architecture". Oh! Sorry again: It's about proven patterns; no chance in your colleague's NIH view ;-)

2
  • NIH syndrome, interesting, I had not heard of this before. Evidently that is the issue that most North American employers are facing with how to manage their employees!
    – pay
    Sep 1, 2016 at 20:38
  • @pay I'm not sure that this is limited to North America ;-) It's always tempting to go for solutions that we already used in the past with some success. It's the comfort zone. But one should always remain open to new ideas and constructive dialogue with challenging colleagues. After all, "You travel faster alone, but farther together."
    – Christophe
    Sep 1, 2016 at 21:37
16

A key insight many people miss is that software design is contextual. It exists to reach business goals, and different goals may require different approaches. Put differently, there is no design that is always best, even though there is always a best design.

Design patterns are standard solutions to standard problems. However, if you do not have the problem, solving it is a waste of effort.

The key difference between waterfall and agile software design is when design decisions are made. In waterfall, we gather all requirements, identify which design patterns we need, and only then start coding. In agile architecture, we follow the YAGNI pricinple to defer design decisions until the last responsible moment, when we know as much about the choice as we possibly can.

That is, in waterfall, design patterns tend to be applied if their need is anticipated, in agile, when they are actually needed. As a consequence, agile projects tends to apply design patterns less often, because not all anticipated needs are actual.

1
  • 1
    +1 for Design patterns are standard solutions to standard problems. I'm a bit disapointed to not saw that in more upvoted answers. This so require first to identify if your problem you're wokring on match to a standard problem, and really often, they will aniway.
    – Walfrat
    Sep 1, 2016 at 11:06
8

Design patterns aren't really called design patterns because they prescribe what to do. Design patterns are design patterns because they describe what has been done before. Some developer or developers designed a method that accomplished a particular task well, and were able to apply it to similar situations with similar results. That's all it is. Many patterns have inherent strengths and weaknesses, and it is up to the educated developer to evaluate the technological and business needs to determine an appropriate pattern to apply.

In that light, unless you are truly committed to writing 100% one-off code, where no concepts or implementations are usable from one use case to the next, you are almost certainly using at least some design patterns. They may not have flashy, common names like "Repository" or "Unit of Work" or even "MVC", but that doesn't make them "not a design pattern".

6

I usually like to think of it in the way of - say - "navigation" using the GPS. When learning 'best practices' and 'design patterns' - you learn to take the GPS navigation route. But when you know the area, you'll often learn that driving down a side road will lead you past problem areas, get you there faster and/or better. It's much the same when it comes to these things - experience makes you able to deconstruct your toolbox and take short-cuts.

Learning design patterns and learning "best practices" means you gain an understanding about the idea behind so you can choose in a given situation. Because real life situations are often more complex compared to theoretical situations - you will often have constraints and issues not found in the textbooks. Clients/Customers want their product fast and usually cheap; You need to work with legacy code; You need to interact with third party tools which may very well be black boxes and ineffective; and all sorts of things. Your situation is specific - best practices and patterns are more general.

One major reason that many people on sites like SE will give you 'best practice' answers and 'design pattern' answers is that because they're answering in a general and abstracted solutions and thereby it helps provide a common language for solving a type of problems. And to get you to learn.

So - no - design patterns are not frowned upon in Agile development environments; development however is rarely general and abstract enough to fit a pattern perfectly and the (experienced) developer knows this.

5

Adding a new field to the UI/database/Data layer takes 2-3 hours to do, where as in his code it takes 30 minutes.

If you want to "optimize" a design you need to say what you're trying to optimize.

For example, a racing bicycle is an optimized vehicle ... and a Boeing 747 is also an optimized vehicle ... but they're optimized for a different set of requirements.

The idea of the "MVC" pattern, for example, optimizes for things like:

  • Different views of the same model (view is independent of model)
  • Each layer can be developed separately (e.g. by different teams) and tested separately (unit tests) before integration
  • etc.

Whereas his code might be optimizing for something else, for example:

  • Minimal lines of code
  • Easy for one person to make a change which affects all layers (by not having really distinct layers at all)
  • etc.

Pattern descriptions start with a description of the problem which pattern is intended to solve. If he thinks it's "best practice" not to use a specific pattern, then (assuming it's not a stupid pattern, assuming it's a pattern which is useful sometimes) I suppose that he doesn't have/experience the specific problem which that pattern claims to solve, and/or he has got a different (bigger or more urgent, competing) problem which he's trying to optimize for instead.

1
  • "by not having really distinct layers at all" -- or, to be fair, by having acceptable "default behaviour" that propagates through the layers. For example, web-based SQL admin apps are a presentation layer that automatically updates itself when the database layer changes. It's just that, other than for limited uses, they don't actually present your data the way you want it presented to users :-) Half an hour seems incredibly quick to add a new field, suggesting that there's no significant UI to design in connection with the new field, layered or otherwise. Sep 5, 2016 at 8:57
4

Design patterns are tools. Like tools, there's two ways to use them: the correct way, and the incorrect way. For example, if I give you a screwdriver and a nail, and ask you to join two pieces of wood together, you should ask me for a hammer. Hammers are used for nails, while screwdrivers are used for screws.

Too often, a design pattern is advertised as the One True Way, which is often only true when particular problems arise. Junior developers are often like children when they find something new to play with; they want to apply that design pattern to everything. And there's nothing inherently wrong with it, so long as they eventually learn that Pattern A applies to Problem B, and Pattern C applies to Problem D. Just as you don't use a screwdriver to drive nails, you don't use a particular pattern just because it exists; you use the pattern because it's the best (known) tool for the job.

The flip side of patterns are anti-patterns. Things that have proven time and again to be bad, usually in terms of execution time or memory. However, both patterns and anti-patterns do no good to the developer that doesn't understand why they exist. Developers like to think that what they're doing is new and inventive, but most of the time, they're not. It's likely been thought of before. People before them have created the patterns because of experience.

Of course, junior developers often seem to come up with new ways of doing old things, and sometimes those ways are better. However, too often it ends up being a case of the Dunning-Kruger effect; the developer knows just enough to make a functional program, but doesn't understand their own limitations. The only way to get past this seems to be through experience, both positive and negative. They ignore patterns because they believe themselves to be superior, but don't know that, in reality, 10,000 developers have already used a specific design, and then discarded it because it was actually bad.

Agile favors "getting things done responsively" in regards to rapidly adjusting to evolving client needs. It neither favors design patterns nor despises them. If a pattern is the fastest, most reliable method, then the developer should use it. If a particular pattern would cost more time than simply "getting it done," using something that's not-a-pattern is likely okay (assuming, of course, that performance isn't severely degraded, etc). If no known pattern can be found, designing their own is preferred over telling a client "no." Clients, especially paying clients, are usually right.

Anyone who claims that patterns are The Way, or claims that patterns are The Bane Of Existence, are wrong. Patterns are tools, meant to be applied to specific situations, and have varying degrees of success based on circumstances. This is a Truth, one that doesn't depend on if you chose MVC or not, if you use Data Transfer Objects, or not, etc. What matters is implementing code in a reasonably short time frame, that performs reasonably well for users, and is reasonably free of logic bugs.

Usually, patterns will allow a coherent form of design, and will perform better than ignoring all patterns in favor of writing 100% original ideas, but you can't avoid all patterns. For example, if y = x + 5, are you really going to write y = x + (5 * 3 + 15 / 3) / 4, just to avoid the pattern of writing x + 5? No. You're not. You're going to write y = x + 5, and move on to the next problem.

People use patterns every day, and that's okay. What matters the most is having code that's logically functional, rarely crashes, and is user-friendly. Nothing else matters more than that.

1
  • I think the caveat with this are situations that, based on your 'current' understanding of the problem and domain, you can create a new class or follow a pattern that applies to the situation, but then the next day a client wishes for you to make customizations for them to some small facet that other clients will not want in their version. Consolidating a codebase that caters to the needs of 2 dozen clients and avoids copy pasta seems impossible to accomplish. I just ran into this today when refactoring an old mail merge process.
    – Igneous01
    Sep 1, 2016 at 16:15
2

You can't 'avoid design patterns', except I guess by avoiding designing any two parts of your system the same way (which I don't recommend and I doubt your senior developer is doing). What he probably means is 'avoid blindly using a design just because it adheres to a design pattern'. Thinking about what you're doing is definitely a 'best practice', and one universities ought to exist to teach; sadly, that doesn't seem to be happening.

2

Design patterns are not antithetical to agile practices. What is antithetical to agile practices is using design patterns for the sake of using design patterns, the common practice among fresh graduates and students to think along the lines of "how are we going to solve this problem using a factory pattern".

Agile means choosing the best tool for the job, NOT trying to shape the job to fit the tool you've selected.
And tbh that's what ALL common sense development practices come down to (though often you of course have to make compromises because the selection of tools you can choose from is usually restricted by corporate standards, license restrictions (like GPL and sometimes other open source tools often can't be used, especially when building software for resale), and things like that.

Your colleague/friend probably objected to your code not because it uses design patterns per se, but because it's an artificial construct designed to show the use of a specific pattern when another design would have been better (though often subjective, I've (and many with me no doubt) have seen plenty of examples where the forced use of a specific design pattern led to ugly, hard to maintain, and highly inefficient code).

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