Thinking back, I mostly used patterns like adapter, strategy, factory, template method - whatever helped me get the job done.
There are some patterns I probably never used, or only used rarely, like flyweight or memento.
What are the more “exotic“ patterns you used? In which context? What pattern is the most underrated?
Top comments (15)
I have a love-hate relationship with the Visitor pattern; sometimes it seems the best (only) way of solving the problem in front of you, but it still feels unwieldy, hard to follow and honestly a bit of a hack.
If I can, I'll treat the temptation to use Visitor as a clue that the model is wrong and refactor ;)
What kind of problems have you solved with it? I know that it fits best when processing e.g. tree structures.
Exactly - operations on a graph of objects of different classes.
CQS - Command Query Separation. It does not seem very well-known. It is especially nice for public APIs because if makes your user less afraid about the possible side effects of calling your functions/methods. They know exactly when they are making changes.
I would even go so far that the event driven architectural style in general is usually underrated, with respect to encapsulation/decoupling it provides. Even something like the ports&adapter architecture (or clean architecture) that specifically aims at decoupling is usually explained in terms of defined methods of known interfaces.
I like this one. I think a lot of people writing Redux code are using it and aren't aware of it, if they are using actions & selectors.
The Interpreter pattern is one that I am rediscovering lately, or at least a limited variation of it (more in line with Free + Interpreter). The Elm Architecture (aka MVU) has an interpreter built in for side effects. For example, you can return a declared Http side effect, and it will later run an interpreter to perform the side effect, then send a message back to your decision logic with the result.
So the advantage of Interpreter, is that it can turn processes which need side-effects into purely deterministic code. That makes it very testable and easy to isolate the discrete steps of the process. I am planning to make a post on how to adapt MVU for the server-side -- represent effectful processes as pure, testable functions. (And actually, there's no V anymore and Effects are added, since Elm does not allow you to create your own within Elm.) I have been internally calling it Decide-Perform, and it has more than a passing resemblance to an OODA loop.
Cool. I have to admit I didn't know that one. I'm looking forward to the article.
I don't have an article yet. But I recently posted a gist with a code example. The code fetches AWS Simple System Manager Parameter Store values. Maybe it is terrible. See what you think. Here is the gist.
The upshot is that the
update
function is pure/deterministic/referentially-transparent and therefore very testable. You can even test that the correct side effects are triggered (without actually running them).Hi Bertil,
Two I've used are State and Proxy.
Proxy we used extensively in a java based test automation framework. It simplified the tests for the user while allowing us to make them more reliable. One example is in UI testing, ensuring the element is on the page before interacting with it. Anyone who has used selenium knows of the dreaded StaleElementReferenceException.
I used State in a java based server side of a web app. An object in the domain could be in one of many states and depending on the state could only transition to particular states. This was combined with the template method to give common functionality to all classes and yet let the algorithms vary
Just read the proof-of-concept, yikes. I think I'll stick with JavaFX for anything serious. Any suggestions for cross-platform frameworks?
Wow that brings back memories, and trying to get it to work in cross-platform :-|, these days I just stick with Electron