6

The question seems to be quite vague, so let me give some background:

I have given the concept of design patterns some thought and stumbled upon the classification used by the Gang of Four:

  • Creational Patterns
  • Structural Patterns
  • Behavioural Patterns

Since design patterns are intended to be solutions for common design problems, the classification should apply to not only to the patterns but to the underlying problems as well.

Somehow the classification seems to make sense and I find it hard to figure out a design problem that cannot be put into one of these categories. On the other hand I find it somehow arbitrary.

Isn't creation a kind of behaviour? Doesn't it sometimes depend on the point of view if something classifies as behavioural or as structural? Why are there creational patterns but no 'destructional' ones?

Is this classification an invention of the Gang of Four or has it been used before? Can it be derived from some theory? Are there alternatives?

While this question is related to my previous one, it differs in two aspects:

  • It is about the classification scheme and not about the patterns themselves.
  • It is not about patterns but about the design problems intended to be solved by patterns.
Frank Puffer
  • 6,429
  • 1
    "Is this classification an invention of the Gang of Four" Yes. "Can it be derived from some theory? Are there alternatives?" No and No. – Euphoric Nov 27 '16 at 19:29
  • Could you split your question into several different questions so it is not so broad? – Tulains Córdova Nov 27 '16 at 23:33
  • 1
    Martin Fowler had been collecting software patterns for many years, so: on one hand, we now know more design patterns than the ones described in GoF, and on the other hand, new patterns keep coming up (some of them enabled by technological breakthroughs such as cloud computing and massive solid state persistent memory), so the list of software patterns will never be complete. Do not confuse software patterns with computer science algorithms. – rwong Nov 28 '16 at 00:21
  • 1
  • @Euphoric, did you mean "no" for "Are there alternatives?" as "yes" is of course the right answer. There are many alternatives: not bothering with such categories, inventing new categories etc. I personally favour just burning all copies of the GoF book to stop people copying their bad coding examples as my alternative. – David Arno Nov 28 '16 at 10:07
  • 2
    I think the reason that you can't find any problems that don't fit these groups is that "behavioural problems" is an extremely vague catch-all... if a problem doesn't encompass behaviour at least in some fashion, it wouldn't actually be a problem, because we wouldn't care about it ... because at the end of the day, we write software for the behaviour it produces. If some code doesn't produce a behaviour we want, we wouldn't write it, because it would be useless. – Periata Breatta Nov 28 '16 at 10:58

3 Answers3

11

The fundamental misconception is that for a given problem there is a given pattern.

Patterns are not lessons about how to code. They are a vocabulary we use to describe patterns we recognize in code.

I can solve any problem in a way that avoids any currently documented pattern. If I do that though I'm going to have a tough time explaining how my code works to anyone else.

It's true that pattern choices are impacted by the problem, but they are also impacted by the language (and it's deficiencies), but mostly they are a mater of personal style.

Any collection of patterns is incomplete precisely because anyone can create a new one. What you've been learning are simply the popular ones.

The popular ones are good to know because I can tell you: "oh, that class is a decorator, you know, the decorator pattern?" without having to go into details about function composition, interfaces, and delegation.

Creational just means the point of these patterns is to construct (initialize) some object.

Structural just means the point of these patterns is to create some data structure.

Behavioral just means the point of these patterns is to behave the way some use case needs the program to behave.

These are very different goals that have nothing to do with classifying a problem. They are parts of solving one. If the problem is getting from point a to b these tell you ways to build a car, navigate a map, and get a drivers license.

And that's all well and good but you can just walk if you like.

candied_orange
  • 108,538
7

Software eats the world. Hence, your challenging question sound like cutting the universe into predefined lego pieces. Different authors have different views about what these pieces could be:

  • GoF used 3 main categories that address usual class design problems
  • Martin Fowler wrote a book entirely dedicated to "Patterns for Enterprise Application Architecture", that identifies different categories of patterns for designing business software architectures. These are split into specific categories such as domain logic, data source, object-relational mapping, metadata mapping, web-presentation, etc...
  • POSA (aka "Patten Oriented Software Architecture") is a collection of 4 or 5 books from Buschmann & al that identify architectural patterns for specific range of problems like concurrent object management, resource management, system, and distributed computing
  • Numberous other books exist about specialized patterns (example software integration patterns)
  • Programming languages come also with some idioms that could be viewed as low-level patterns (e.g. RAII in C++, or Input/output streams in C++, Java and other object oriented languages).

The thing is that these categorizations are not all at the same level of abstraction. They may further overlap.

Finding a general categorization of all software problems seems therefore as ambitious as finding a general programming language that would ideally fit all the programming needs. Or a universal software analysis methods that could decompose any programming problem into predefined pieces.

This just ain't possible : this could be made for known problems as these books have shown. But there are so many new areas or technologies in SW development and so many interaction between all the different parts. I'm afraid you will not find such a general categorization.

Christophe
  • 77,139
2

The GoF patterns are not a comprehensive list of software patterns, nor are they intended to provide a generalized framework for solving computing problems or writing an application.

For the most part, the GoF patterns are workarounds for deficiencies in certain programming languages, and that's all they are.

The three categories of GoF patterns:

  • Creational Patterns
  • Structural Patterns
  • Behavioural Patterns

are merely terms that the authors made up for their book, so that they could conceptually separate the patterns into different buckets.

Robert Harvey
  • 199,517
  • Agreed, at least partly, but my question is not about design patterns. What I am interested in is if there is a sensible classification of the underlying design problems. If these problems are to be solved by patterns, by language features or simply by creativity, is secondary. – Frank Puffer Nov 27 '16 at 19:43
  • 1
    I am saying that you're ascribing more importance/significance to design patterns (and the design problems that they solve) than they actually have. To better classify design problems, look into things like algorithms, data structures, language design and architectures. – Robert Harvey Nov 27 '16 at 19:46
  • Agreed again. The reason why I currently keep posting questions related to design patterns is not that I am a big fan of them. It is just a topic that I am temporarily interested in. – Frank Puffer Nov 27 '16 at 20:02
  • 2
    " patterns are workarounds for deficiencies in certain programming languages" Once again with that misinformation. Patterns are ubiquitous in all languages. Its just different languages (or different paradigms) have different patterns. – Euphoric Nov 27 '16 at 20:22
  • 1
    @Euphoric: Its just different languages (or different paradigms) have different patterns. -- Exactly my point. Were the language already expressive enough to solve the problem for which the pattern was invented, you wouldn't need the pattern. My statement is hardly controversial; go look on some of my other answers for comments that widely support and substantiate this claim. – Robert Harvey Nov 27 '16 at 20:23
  • @Euphoric: A few of the GoF patterns are indeed workarounds for language deficiencies, like the Visitor pattern which would be obsolete if the language supported multiple dispatch. But mostly they are language independent, like "adapter" or "decorator" is useful in any OO language, and cannot be solved in general by making the language more expressive. – JacquesB Nov 27 '16 at 20:24
  • 1
    @Euphoric: Anyway, my real point is that if you're trying to write a program by stitching together software patterns (which, in the case of GoF, are twenty years old), you're probably doing it wrong. Calling them workarounds (which is what they are) gets people thinking about how to write their programs better, instead of satisfying their instinct to follow the herd. – Robert Harvey Nov 27 '16 at 20:30
  • 4
    @JacquesB: The Builder Pattern is a good example of a workaround in Java. It's completely unnecessary in C#, because C# provides optional constructor parameters with default values. – Robert Harvey Nov 27 '16 at 20:37
  • 5
    @RobertHarvey: to be fair, that is not the only problem a Builder can solve, which makes this pattern not unneccessary in C#, only less frequently applicable. Builders are useful when the construction process for an object so complex they justify a class on its own. And I don't see how this could be compensated by a language feature which is currently missing. – Doc Brown Nov 27 '16 at 21:45
  • @RobertHarvey That is incorrect. Builder is not only about optional parameters. It is primarily about separating the code that drives the construction and construction itself. – Euphoric Nov 27 '16 at 21:46
  • @Euphoric: I'll stipulate. It still solves the problem of telescoping constructors, as does C#'s solution. – Robert Harvey Nov 27 '16 at 22:02
  • 1
    Builder also solves polymorphic construction, where the type of the newly created and returned instance from a function may depend on the function's input arguments. Just my two cents. In my opinion, statically typed languages, dynamic languages, and metaprogramming languages each have their distinct patterns that do not make sense across the borders. This is not the same as saying that "there is no pattern outside the border (of my language)". – rwong Nov 28 '16 at 00:29
  • @rwong: That scenario sounds like it could be better served with one or more polymorphic factory methods. Builder is one of the worst software patterns I've ever seen; enormous complexity for a very small benefit. – Robert Harvey Nov 28 '16 at 00:47
  • 2
    @RobertHarvey Agreed on the enormous complexity. Builder should be a last resort, and shouldn't be used unless all other alternatives had been exhausted. But I have seen a few situations where it's genuinely needed. If you ask whether software patterns are dangerous, I would compare that to asking whether car driving is dangerous. There are experienced and inexperienced car drivers, on the same road, and you can't immediately tell who is the inexperienced until bad things happen. – rwong Nov 28 '16 at 00:52
  • 2
    It's the Josh Bloch Builder that simulates named parameters in Java. The GoF builder is a different beast that delegates to lower classes the details of exactly what type to build when asked. These are not the same thing. It's unfortunate that the patterns have such similar names but that's the way it goes in this business. – candied_orange Nov 28 '16 at 01:08
  • The purpose of the builder pattern is "the algorithm for creating a complex object should be independent of the parts that make up the object and how they're assembled.". Optional arguments in C# are cool, but they do not do this. – JacquesB Nov 28 '16 at 08:00
  • @RobertHarvey: There are legitimate use cases for the builder pattern in C#. Foe example building a query using IQueryable in Linq is really an application of the builder pattern. – JacquesB Nov 28 '16 at 11:43