DEV Community

Cover image for Category vs Design pattern
stereobooster
stereobooster

Posted on • Originally published at stereobooster.com on

Category vs Design pattern

There is an ongoing discussion about the difference between object-oriented programming (OOP) and functional programming (FP). Let's talk about similarities instead.

In the previous post, we talked about "atoms": objects and functions. In this post let's talk about bigger building blocks.

What is a design pattern?

Alexander et al. define a pattern as follows:

A design pattern is a three-part rule, which expresses a relation between a certain context, a problem, and a solution. The pattern is, in short, at the same time a thing, ..., and the rule which tells us how to create that thing, and when we must create it.

-- A Pattern Language: Towns, Buildings, Construction, 1977

They become popular after the book "Design Patterns: Elements of Reusable Object-Oriented Software" by Erich Gamma et al. (sometimes referred as Gang of Four - GoF).

There was prior work in this area, for example:

If we follow Alexander's definition there is nothing OOP specific (their book is about architecture anyway). For example, algorithms and data structures could be thought as patterns - if you need a list with O(1) access you can use arrays (or vectors), but the restriction is...

Currently when people say "design pattern" they most likely refer to GoF or similar OOP patterns.

Some people criticize the idea of design patterns.

What is a pattern in FP?

There is no same concept of "design pattern" in FP in sense of "bigger building blocks", the closest thing I can think of is categories from category theory. It is not bigger scale because function itself can be thought as a category.

I don't want to deep dive in category theory so I will give simplified picture, so we can do a simple comparison.

Category theory is a toolset for describing the general abstract structures in mathematics.

As opposed to set theory, category theory focuses not on elements x,y,⋯ – called objects – but on the relations between these objects...

-- ncatlab.org

You should have approximate understanding of what is category after this definition, not precise. We don't need precise because we will compare one pattern to the function as an example and stop there.

Typical critics of categories (in programming) is that it is hard to understand. By hard to understand I mean that they are very abstract and it is hard to relate to it.

A monad is a monoid in the category of endofunctors, what's the problem?

-- Joke from A Brief, Incomplete, and Mostly Wrong History of Programming Languages

Other people may say that categories are easier to understand than design patterns because they are precisely defined (this is math). I look at it from this PoV: I was able to explain what pattern is (I hope), but for category theory, I gave only mare shadow of an explanation.

Strategy vs function

There is a big article which compares design patterns to categories. You can read it if you want more details. We will talk about one approachable example.

Strategy pattern vs function (functor)

The strategy pattern ... is a behavioral software design pattern that enables selecting an algorithm at runtime. Instead of implementing a single algorithm directly, code receives run-time instructions as to which in a family of algorithms to use

In OOP this pattern would be implemented as different objects (or classes) with the same method:

// a11, a2
class AlphabeticCompare {
  compare(x, y) {
    /* ... */
  }
}

// a2, a11
class NaturalCompare {
  compare(x, y) {
    /* ... */
  }
}

In FP there is no need to construct objects for this, instead, we can pass functions as values:

// a11, a2
const alphabeticCompare = (x, y) => {
  /* ... */
};

// a2, a11
const naturalCompare = (x, y) => {
  /* ... */
};

Take away

My idea is to show that there are some core ideas which are same-ish in both paradigms.

Top comments (5)

Collapse
 
bootcode profile image
Robin Palotai

Thanks for the article, didn't know the GH link!

I would take those with some reservation though. For example, randomly looking, the advice to relate Builder with record syntax, smart constructor is very odd.

The benefit of Builder is that it protects from building incomplete/invalid instances. Using record syntax, with dummy default data, doesn't help that at all.

They get the OO Builder wrong too, with using default fields. The builder should explicitly warn on required but uninitialized fields (apart from other checks).

Btw, for Java I recommend AutoValue with Builder, see github.com/google/auto/blob/master....

Collapse
 
stereobooster profile image
stereobooster

I guess you can open issue or PR in GH repository.

Collapse
 
bootcode profile image
Robin Palotai

True. I pass on the opportunity though :)

Collapse
 
wiktorwandachowicz profile image
Wiktor Wandachowicz

Regarding design patterns, please take some time to read following presentation and articles:

Especially the first one is a response to "Design Patterns" book by Gang of Four.
And IMO it's straight to the point. One interesting conclusion might be that OOP languages sometimes create problems that have to be solved by "patterns". But other languages (dynamic, functional) may contain mechanisms to easily solve the same problems, without patterns.

Second and third are somewhat interesting, but very strongly opinionated. Be warned! :)

Collapse
 
codemouse92 profile image
Jason C. McDonald • Edited

Well put.

P.S. Things really get interesting when you combine OOP and FP (which, of course, means you're not fully following either?)