_______ __ _______
| | |.---.-..----.| |--..-----..----. | | |.-----..--.--.--..-----.
| || _ || __|| < | -__|| _| | || -__|| | | ||__ --|
|___|___||___._||____||__|__||_____||__| |__|____||_____||________||_____|
on Gopher (inofficial)
(HTM) Visit Hacker News on the Web
COMMENT PAGE FOR:
(HTM) Patterns.dev
PUSH_AX wrote 3 hours 14 min ago:
I don't think I've thought about patterns in over a decade, maybe I use
one or two without realising it's a "pattern".
verdverm wrote 22 hours 37 min ago:
Is this JavaScript's take on the GOF book selections plus all the
shenans, er "patterns," the ecosystem build tools require?
I was hoping for more high-level architecture based on war stories and
experience. This is pretty basic stuff, which has it's value for people
earlier in their journey, and does seem to have effort put in from a
quick peruse
bmiekre wrote 1 day ago:
Did this get an update? It's been around for a while.
css_apologist wrote 1 day ago:
this site reads like its 2017
its low quality, breadth but no depth
more important is to deeply understand the basics of working with
immutable data. try writing applications with no for loops or forEach
(and actually use the array methods as they are intended), no cloneDeep
hacks and obviously no direct property mutation, always create a new
object.
in real world you still use for loops plenty, but as a junior its good
to see what its like to live without it for a while.
dominicrose wrote 1 day ago:
I've used Clojure/Script in the past and it's good to enforce working
with immutable data.
Immutable.js has similar data structures but it's not the standard
way of doing things and uglier to debug.
Using standard objects, immutability is not enforced in JS and
throwing a few Object.freeze calls won't change that so we lose half
the benefits that Clojure would bring: parallel/concurrent
programming benefits, easier deep equality checks, performance...
If the code is not performance sensitive and can run in a single
thread, simply "not mutating some of the mutable data" is a start for
someone interested in immutability.
That's what ramdajs does, it doesn't invent new data structures or
freeze objects but simply returns new ones.
Only a few functions from ramdajs are actually useful in 2025 since
JS has evolved with things like array/object destructuring and "..."
but in any case it's an inspiring library.
css_apologist wrote 1 day ago:
I've used these things. IME, nowadays it's not worth the bundle
size to bring in these libraries. map/filter seems quite optimized,
{...obj} is fast since its only shallow. Yes it does come down to
practices vs better libraries, but in practice, it's fine IME
One thing to note, i was very excited that we have a bunch of lazy
methods on Iterator protocol, but they are slow as shit as of
earlier this year.
I wrote a parser a year ago with extreme use of .map (every step of
processing was cloning the tokens), and i thought, let's migrate it
to lazy iterator - it got ~10x slower :(. The compile time was fine
for my use cases, so i didn't give immutable-js a try, but it was a
surprise
I did some benchmarks on map+filter vs mutable for of + push, and
on firefox up to 200-300 elements map+filter is actually faster
(unforunately not on chrome).
Of course, its not the best, but my experience is that modern js
engines are fast enough for most use cases to not have to bring in
any libraries anymore
css_apologist wrote 1 day ago:
although this article does get me thinking of documenting the
âpatternsâ i use, and why.
andybak wrote 1 day ago:
"Design Patterns are a sign of missing language features". [1] [2]
(HTM) [1]: https://wiki.c2.com/?AreDesignPatternsMissingLanguageFeatures
(HTM) [2]: https://norvig.com/design-patterns/design-patterns.pdf
(HTM) [3]: https://medium.com/@letsCodeDevelopers/your-design-patterns-ar...
css_apologist wrote 1 day ago:
a lot of these are misleading, or ungrounded
see the prototype, and observable pattern
they explain the basic concept, but in the only way you would never use
it in real life
emaro wrote 1 day ago:
Design patterns can be really helpful. In my previous job I worked on
enterprise .NET applications. It made sense to use common patterns,
because most applications were big and the patterns made it easier to
understand unfamiliar code, within an application but also across
different teams and applications. New projects looked familiar, because
the same style and the same patterns were used.
Now I'm working on an old (+10 years) JS application. Similar patterns
were implemented, but in this case it's not helpful at all. The code
looks very corporate and Java EE style, with a ton of getters and
setters (`getName() {}`, not `get name() {}`, factories, facades,
adapters, etc, etc. It's usually completely unclear what the benefit of
the pattern is, and code is more complicated, for instance because
creating new instances of business objects is split into `Object.build`
which calls `new Object`, with no guidelines at all what part of the
initialization should be in `build` and what should be in the
constructor.
The gist of my comment is that patterns can be useful, but usually
they're overused and if you implement one without understanding why and
without benefiting from faster understanding the code because the
pattern is applied consistently over multiple instances, the result is
worse than just implementing what you need in a readable way (YAGNI).
khannn wrote 21 hours 45 min ago:
People were shifted from Java to Javascript and kept the Java
patterns and maybe the organization had standards requiring their
use.
ozim wrote 22 hours 29 min ago:
I see a lot of comments about how patterns are useless from people
writing toy apps or at least ones that never had to deal with really
enterprise scale stuff. So for me they are like people building a
shed screaming at people building sky scrapers that no one ever needs
to pour so much concrete to form a foundation.
Parent comment is not like that.
daxfohl wrote 23 hours 59 min ago:
Yeah, I've seen (okay, and been responsible for) a lot of "the road
to hell is paved with good intentions" due to jumping to some pattern
or other because, well, it feels like the right thing to do. It makes
the code cleaner at delivery time, and is usually very intuitive when
the design is fresh in your mind. But IME it doesn't take long before
that freshness goes away, and the next time you look at it (let alone
anyone else) you find it hard to follow the logic anymore. Usually
"constructing" the pattern and "executing" the pattern are in
different places in the code, and there's not a straightforward way
to mentally step through one without continually cross-referencing
the other. At some point you wish you'd just written one long switch
block that you could step through.
And that's all before new requirements that break the pattern, or
other engineers that don't have time to grok the design and hack in
something that looks like a switch block for their thing, which
eventually takes over most of the code anyway.
layer8 wrote 1 day ago:
I would put it slightly differently: Patterns (including
anti-patterns) happen whether you call them such or not. Any
developer will sooner or later come up with patterns like Adapter or
Builder or Composite or Iterator. In that sense, patterns are not
invented, but discovered. The benefit of design patterns is to be
able to communicate these discovered patterns, and to define agreed
names for them, so that you don't have to describe the pattern each
time you talk to another developer, but can refer to it by a
well-understood name. (Or when not yet well-understood, can refer to
the corresponding pattern description.) It extends the language we
use to talk about software design.
The point of design patterns is less about the individual patterns,
than about having "design pattern" as a general concept of coding
patterns relevant to software design, that you name and describe
because they keep reoccurring.
naasking wrote 23 hours 50 min ago:
Yes and no. Some patterns exist because the language isn't
expressive enough. This is one reason why the patterns made sense
in the OP's .NET programs, but made less sense in JS. JS simply
doesn't require as much ceremony for some things because it's
dynamically typed and reflection kind of comes for free.
moron4hire wrote 22 hours 1 min ago:
I would say that reflection in JS is terrible compared to .NET.
You can only just barely figure out what is in an object, but
it's a hell of a time figuring out what any of those things can
do. I wouldn't so much as call what JS does "reflection" any more
than "making objects out of poorly implemented hashmaps."
no_wizard wrote 20 hours 14 min ago:
>You can only just barely figure out what is in an object
There's a couple really well documented and understood ways of
doing this in the language. I'm not sure what you're
specifically referencing without more information.
>I wouldn't so much as call what JS does "reflection" any more
than "making objects out of poorly implemented hashmaps."
Is this anymore different than .NET deriving everything from a
base `System.Object`[0] type?
Also, what is missing in JS reflection wise that you can't do
that would make sense for its environment? (namely, this
excludes compile time reflection stuff I know .NET can do, it
wouldn't make sense for a scripting language as it currently
is)
[0]:
(HTM) [1]: https://learn.microsoft.com/en-us/dotnet/api/system.ob...
moron4hire wrote 19 hours 1 min ago:
In JavaScript, one can tell if an object has a method by
iterating over the object keys and seeing if the value is
`instanceof Function`.
But that actually tells you very little. You might be able to
tell that it takes a certain number of parameters, if you are
running on a system that implements
Function.prototype.length. But you will have no way of
telling what the arguments to those parameters should be, or
even what they were even named. There's no way to tell if the
function is a method that needs to be `.call()`ed with a
value for "this", or if it's just a function that happens to
live in an object literal, or if it's actually a class
constructor that must be called with `new`! And there is
certainly no way to tell whether the function returns a
value, say nothing about the type of value it returns.
With .NET reflection, I can do ask those things I lament
missing in JS, and guarantee the type safeness of it.
matheusmoreira wrote 16 hours 14 min ago:
Isn't this just a fundamental limitation of dynamic typing?
moron4hire wrote 15 hours 40 min ago:
Most of it is not. Most of the data necessary to support
reflection should be available to the runtime or else it
wouldn't be able to operate. The runtime is parsing the
syntax of the function, it should be able to tell if all
exit conditions have a return of any kind. It should be
able to tell me at least the names of the parameters. It
should know if a function is bound to a "this", or of
it's a constructor. It just doesn't give any way to tell
me.
actionfromafar wrote 21 hours 28 min ago:
"Javascript" === "Chaotic neutral lisp"
socalgal2 wrote 19 hours 32 min ago:
lisp to me is (1) the language itself is a lists of lists (2)
defmacro lets you manipulate those lists of list at compile
time. JS doesn't this do either of these at all AFAICT and so
is absolutely nothing like lisp.
Most lisp programs are about writing DSLs using defmacro.
What's the similarity to lisp except that both are
programming languages?
actionfromafar wrote 17 hours 31 min ago:
Let me ask you instead, do you consider there to exist any
Lisp which has no compiler?
moron4hire wrote 21 hours 6 min ago:
Yeah, I don't like the comparisons of JS to Lisp, because I
think they mostly center on the existance of the map and
filter methods of Array. To me, that's just not what Lisp is
about. C# has map/filter/etc, and we don't say C# is-a Lisp.
And there are many other such features that were once
unique/unique-ish to Lisp, that were major selling points for
using Lisp at the time, but are now pretty common across a
very diverse set of languages. Garbage collection being one.
Higher order functions being another.
Lisp's big idea that stuck to being unique to Lisp is
homoiconicity. It's the one thing that continues to be
valuable enough to warrant using Lisp, despite everything
else that has been stolen and copied.
Of course, not that I ever used Common Lisp, and not that I
use Racket anymore. I enjoyed the hell out of programming in
Racket. Up until the point I needed to access a database.
Man, who's got time for that Jankasarous Rex? But I really
would love a homoiconic language for the .NET CLR. That would
be pretty sweet.
actionfromafar wrote 17 hours 29 min ago:
Well put.
zeroq wrote 1 day ago:
I would go even further.
For me design patterns are more of vocabulary than a tool.
It's not about - hey I found this book and we'll be using these
building block from now on - rather, it's about having words that
everyone immediately recognizes and associate with exact same
ideas.
baq wrote 1 day ago:
design patterns are a language, it's just that the programming
language they're being implemented in doesn't support them natively.
e.g. observer pattern in java is what, [array of functions].forEach()
in js? not worth calling that by name. another example, singletons -
in Python, it's just a module (caveats apply obviously, but if we
apply them, some also apply in java).
this is why designing a minimal language to make it 'simple' is
misguided: you'll end up having to reinvent the design pattern
language anyway. there are good reasons to design a simple language,
but simple for the sake of simple is missing the point.
jonkoops wrote 1 day ago:
This is a common thing I see when developers that come from an OOP
enterprise environment familiar with Java, C#, etc. do JavaScript,
they try to use all the same patterns, default to classes for
everything. It just doesn't fit the language.
threetonesun wrote 1 day ago:
It was fascinating to me to see JavaScript add the class keyword,
have it be widely adopted thanks to React, then just a few years
later seeing `class` in JavaScript code is, as you said, a clear
sign a Java/C# dev was here.
arscan wrote 23 hours 33 min ago:
I havenât done JavaScript in a long while, is using âclassâ
not a favored way of writing JS these days? I wrote JS heavily
pre-class, and never really got comfortable using it before
switching my focus to other languages.
gcau wrote 21 hours 30 min ago:
The poster you're replying to is plain wrong, using "class" is
ubiquitously common in the javascript/typescript world, it's
the idiomatic way to create classes, and it has better
semantics than trying to use prototypes. You might compile away
the class keyword for compatibility, though.
thunderfork wrote 15 hours 12 min ago:
I think the real sign of this is a class where all the
members are static, or pure data classes - ie, classes as a
default rather than classes for things where classes make
sense
threetonesun wrote 16 hours 56 min ago:
I'm not denying the existence of class in JavaScript, but at
least from what I've seen when React went to functions so did
most of the JavaScript community that had moved to class
based syntax, except for those who worked with Java/C# as
well.
kbolino wrote 18 hours 34 min ago:
But you don't have to do either of those things. There's a
third way, with functions and bare objects. I'm not sure
that's what GP meant, but a lot of the JS I've written (which
tends to be for the browser, mostly vanilla, and
quick-and-dirty, to be fair) never touches classes or
prototypes. The JSON data being produced/consumed is just a
bag of fields, the operations on the document are just
top-level functions, events get handled in callback closures,
responses to HTTP requests get handled with promises, etc.
Sprinkle in some JSDoc comments and you even get fairly
workable autocomplete suggestions. Of course, the web APIs
are built on prototypes/classes, so it's not like they're
totally absent. But with things like data attributes,
querySelector, and HTML templates, the usual needs for my own
code to be OOP (or even structs-with-methods a la Go/Rust)
just don't emerge that much.
arscan wrote 15 hours 21 min ago:
Yeah, I would do a lot with plain objects, and using
closures and iifes to do encapsulation and what-not. It was
ugly and a bit of a pain, but once you learned how it all
worked it made sense and was doable. I felt that classes
were a bit of a bolt-on that violated my own internal
understanding of how JavaScript worked, but by that point I
was moving on to other stuff so never really got used to
it.
skydhash wrote 1 day ago:
A lot of patterns only make sense in languages like C# or Java, which
are inflexible by design. You have two hierarchical trees
(inheritance and namespaces) that you have to work around. With
something simpler like C, Go, JavaScript, you donât have those
obstacles and a solution can be way simpler to implement.
liampulles wrote 10 hours 44 min ago:
I went from Java to Go for my last job. I think there is a
reduction in pattern stuff but there are still many (at least in my
project).
Java is kind of "begging" for patterns IMO, with all its static
package protected final stuff and beliefs around encapsulation. Go
is plainer, which is to its benefit.
mrsmrtss wrote 21 hours 26 min ago:
How do optional inheritance and namespaces (which you can ignore to
use a single global namespace) make a language inflexible? If
anything, these traits make your language more powerful, not less.
ssrc wrote 1 day ago:
Some patterns in the GoF book only apply to C++/Java as they were
in 1994, but I don't see any reason why other languages would have
no useful patterns. The Linux kernel (C) is full of patterns for
example.
Funny thing, Peter Norvig also has this position, that patterns
only apply to languages like Java, but his book on Lisp and the
Python course he had on Udemy (?) are super-pattern-y.
richardlblair wrote 1 day ago:
Somewhat true - I usually find that in these languages the patterns
are there they are just less obvious.
bingemaker wrote 1 day ago:
Looks more or less like GoF? Maybe compressing files and optimizing 3rd
party js files are not patterns.
dkersten wrote 1 day ago:
I hate that singleton is first.
Singletons are just globals with extra steps, and have all the same
problems globals have, just people (especially juniors) think they
somehow are better.
In reality theyâre worse because they conflate global access with
enforced single instance. You almost never need to enforce a single
instance. If you only want one of something, then create only one.
Donât enforce it unless itâs critical that thereâs only one.
Loggers are often given as an example of a âgoodâ singleton and yet
we often need multiple loggers for things like audit logs, or
separating log types.
Instead of singletons, use dependency injection, use context objects,
use service locators, or⦠just use globals and accept that they come
with downsides instead of hiding behind the false sense of code quality
that is a singleton.
sh4rks wrote 1 day ago:
This looks like an excellent resource for interview preparation.
Bookmarked.
pedrozieg wrote 1 day ago:
Most teams donât fail because they picked the wrong framework; they
fail because they never ship enough iterations for it to matter.
Anything that reliably shortens that loop is âgood tech,â even if
itâs ugly, uncool, or built on last decadeâs stack.
rswail wrote 1 day ago:
Patterns are needed for languages for which the actual underlying
concept is unavailable.
For example, prototype pattern is for languages that don't have a way
to express interfaces/traits etc as something that can be attached to
other language entities.
pajtai wrote 1 day ago:
Looks great. Wish it had a table of contents. Am I missing it?
socketcluster wrote 1 day ago:
I find that the more senior you become, the less you rely on software
design patterns.
Juniors often think that learning design patterns is some kind of
career hack which will allow them to skip ahead a decade of
experience... There is some utility in many design patterns but the
problem is that juniors often miss the nuance and the motivation behind
the patterns and they tend to misuse them; often creating more
complexity than they would have created had they not used design
patterns.
There are situations where design patterns may be useful but they're
much more rare than most people think. A lot of juniors seem to think
that every problem requires them to apply a design pattern from their
toolbox. They try to frame every problem within the constraints of
design patterns that they know. This can create problems.
In fact, there are many coding patterns which are far simpler than
'design patterns' and much more useful, but nobody talks about them
because they're too trivial to discuss. For example, I've seen people
write code which relies heavily on design patterns but then that same
code uses an O(n^2) nested loop to find items that are common between
two arrays. There is a simple 'pattern' you can use to store the items
of the first array in a Set or HashMap and then finding common items is
O(n) because Set and HashMap lookups are O(1)... Very useful pattern
but I don't believe it has a name. I use it literally ALL the time. The
idea of storing intermediate state in some kind of HashMap is a
game-changer IMO but there's no name for that pattern of coding. In
general, knowing what data structure is most appropriate for various
scenarios is a game changer... But still, don't abuse. Basic data
structures like arrays are fine most of the time.
Anyway, it's good to absorb the wisdom behind some design patterns but
you should not try to fit every problem to them and dont say stuff like
"For this problem, I applied Design Pattern X" - If you do, senior
engineers will know you're a junior. If you use a design pattern
correctly, it will probably not look exactly like in the textbook. It's
kind of hard to give it a name. It may be a mix of patterns. It's the
principle that counts. Reality is too complex for rigid design
patterns.
On the other hand, some design patterns are too common and obvious to
deserve a name. For example, the factory pattern is super common... I
use it all the time but it's so basic and obvious that I will sound
like a total noob if I go around calling my function "socket factory
pattern"... I will call it "Utility function to obtain a socket" or
something. I will never refer to it as a factory pattern, it's a bit
cringe.
Jaxan wrote 1 day ago:
> Very useful pattern but I don't believe it has a name.
This is an instance of âuse the right data structure for the
jobâ. To me it has little to do with architectural design (where
design patterns live), but it has to do with algorithmic design.
spopejoy wrote 16 hours 11 min ago:
This is the thrust of much of the excellent "Algorithm Design
Manual" by Skiena -- choosing the right data structure to model
your problem can take you 95% of the way toward the best solution.
Izkata wrote 1 day ago:
> For example, I've seen people write code which relies heavily on
design patterns but then that same code uses an O(n^2) nested loop to
find items that are common between two arrays. There is a simple
'pattern' you can use to store the items of the first array in a Set
or HashMap and then finding common items is O(n) because Set and
HashMap lookups are O(1)... Very useful pattern but I don't believe
it has a name. I use it literally ALL the time. The idea of storing
intermediate state in some kind of HashMap is a game-changer IMO but
there's no name for that pattern of coding.
This is a "hash join" in relational databases. You can see it in the
query planner output of at least postgres.
DHRicoF wrote 1 day ago:
For your example, if both lists are small enough, the constant factor
on the cost of creating the hashmap eliminates any advantage you
could have. Anyway, it's not like most places were I've seen a nested
loop used for search the developer had cared. Today I am in a bad
mood.
I have to touch some of the most unnerving modules in a legacy
project and everything is a trap. Lot's of similar repeated code with
ugly patterns and some big brain trying to hide the ugliness with
layers and layers of indirections and inheritance, and calling it
clean because there is a factory class. The biggest joke? each
implementation have a different interface for key methods, so later
you to check what instance got created.
I want to keel myself. Anyone could assist me in a seppuku?
sureglymop wrote 23 hours 23 min ago:
Don't kill yourself. Stop and leave. Every day you will build up a
tiny bit more resentment and then first you will become more
cynical but eventually you will burn out. Be proactive and leave
this behind, move on with life.
viraptor wrote 1 day ago:
I wouldn't say it's cringe. A factory is a factory. Calling it that
in the code may not be the best idea, but having the shared
vocabulary is nice. Basically, patterns work well when they're
descriptive rather than prescriptive.
There are two cases that are unique though: state machines and
visitors are so much things on their own, that you'll use those names
almost every time you run into the pattern.
zelphirkalt wrote 23 hours 20 min ago:
The visitor pattern is my go to example for patterns, that you
don't really need, when you have a language that has first class
functions, which implies among other things, that you can pass
functions as arguments, like you can pass anything else.
The magical "visitor" pattern becomes nothing more than simple
callback passing or passing a function, which is one of the most
natural things to do in a modern programming language.
State machines at least are useful as a conceptual thing, to find a
way to think about how one solves a problem, no matter how they are
ultimately implemented in the end.
vips7L wrote 21 hours 3 min ago:
I've always seen the visitor pattern as a poor-mans pattern
matching. How do you solve the same thing with callbacks?
zelphirkalt wrote 14 hours 57 min ago:
Instead of defining a Visitor interface and then making objects
to implement the interface and then passing those objects to
whatever traverses a graph or iterates through something, you
pass the function, that will be called, by whatever traverses a
graph or iterates through something.
microtherion wrote 1 day ago:
> A factory is a factory.
Yes, but what about factory factories?
(HTM) [1]: https://factoryfactoryfactory.net
TINJ wrote 1 day ago:
> For example, I've seen people write code which relies heavily on
design patterns but then that same code uses an O(n^2) nested loop to
find items that are common between two arrays. There is a simple
'pattern' you can use to store the items of the first array in a Set
or HashMap and then finding common items is O(n) because Set and
HashMap lookups are O(1)... Very useful pattern but I don't believe
it has a name. I use it literally ALL the time. The idea of storing
intermediate state in some kind of HashMap is a game-changer IMO but
there's no name for that pattern of coding.
Isn't this called 'dynamic programming'? It's actually a habit people
should pick up when grinding leetcode.
arethuza wrote 1 day ago:
If you already have Sets handy - why not use the Set Intersection?
(Assuming the Set implementation has that capability).
zelphirkalt wrote 23 hours 17 min ago:
Putting both contents (lists, arrays, whatever you have) into
sets, and then calculating the intersection might be more
expensive than building the intersected set right away sourcing
both non-set contents, I imagine. Though it would probably be
easier to read and understand. But that can be solved by naming
of functions that process the 2 non-set things.
viraptor wrote 1 day ago:
No, dynamic programming is when you split your bigger problem into
a smaller one + 1 step to get to your bigger size. Then apply that
recursively until you solve the trivial problem at the end and get
back the answer for your original problem size.
palata wrote 1 day ago:
I see it as a common vocabulary to talk about tools. It's simpler to
say "I made a singleton" than to describe it.
Just like we have words for a nail, a screw, a hammer. If you had to
say "I used a tool that I find works well with nails", that would be
annoying and ambiguous.
Now of course, if you quickly screwed something with your swiss-army
knife and a junior came and told you that this is wrong, because you
should always use a proper screwdriver, and therefore you should rent
a car and drive 30min to go buy it right now, you would kindly tell
them to fuck off. Doesn't mean that there is no value in the concept
of a screwdriver itself.
Yokohiii wrote 1 day ago:
You point out the cultural issue that this creates and sweep it
under the rug, violently.
The thought model complicates the process of writing new code,
"what pattern do i need here?" and the perception of existing code,
"oh this is pattern X, why isn't that communicated clearly?". The
truth is that design patterns are at best stagnant in quality and
quantity over time (GoF is over 30 years old!), but the quantity
and quality of problems is infinite.
I've thought in patterns quite some time in my early career. With
my colleague back then everything was an pattern and we were kind
of in sync with that approach. But it quickly falls apart if you
have peers that are less try hard on it. You can spend days, weeks,
months to study design patterns and then have to explain it to
someone in 5 minutes that simply doesn't care. I can't blame anyone
to not care, so that has to be accounted for.
I think the common language argument is tempting, but also too
stressed. Good and useful programming knowledge is bound by
reality. An integer is a indisputable thing that is always useful.
A "singleton" is just a fancy rephrasing of "global state".
palata wrote 1 day ago:
I did not mean "everybody has to learn the vocabulary". I meant
the opposite, actually: it's fine not to know the word for the
tool (I don't enjoy reading about patterns just to learn about
patterns, it's not my thing at all).
Say I build a tool that makes it easier for me to drive a nail
and call it a "Naildriver". If I show it to a colleague, they may
be able to tell me "oh, this is generally called a hammer!".
Maybe they will even tell me how I may improve my hammer, because
they happen to like to learn about hammers in their free time. Or
maybe now that they said it's a known concept, I will enjoy
reading about hammers online (doesn't mean I will now read the
entire encyclopedia of tools).
The fact that there is a name for the concept ("it's called a
hammer") does not say you have to know the word. It's just useful
to have a word for it, because then we can reference it in
discussions and share knowledge about it more easily.
berkes wrote 1 day ago:
The other thing that design patterns allow, is to learn
pitfalls, applications and other attributes about them.
To keep in your analogy, if you have a 3KG naildriver with a 2m
handle you'll quickly find out that driving nails into a
drywall with that leaves you with no wall. And that it's a bad
idea to use a "Naildriver" to drive these
"spiralled-slothead-nails" (aka screws) into wood.
But with a common language, such as design patterns, you can
easily learn where they are good, what their limits are, in
what cases other patterns fit better, and what pitfalls to
avoid and so on.
If I search the web for "why is it so hard for my naildriver to
drive in spiralled-slothead-nails" I'll get zero results. But
when I search for "why is it hard to hammer in a screw" I'll
get good results. May sound like a silly example, but for me
that sillyness illustrates how obvious designpatters should be.
palata wrote 1 day ago:
I totally agree with that!
And it doesn't mean at all that everybody should learn the
whole encyclopedia of tools by heart. But having it
formalised somewhere is useful: as soon as someone tells me
"what you're trying to do sounds like this design pattern", I
can start searching and reading about it.
Of course if that someone tells me "you suck, you should know
that there is a design pattern for that because you should
read about design patterns every night before you go to
sleep", it will be different :-).
Yokohiii wrote 21 hours 42 min ago:
I have mixed feelings about this.
I think Julian Assange once said he would refer to things
in discussion just as "Tomato" (or similar), in discussion
to have a shortcut for something unnamed with some meaning.
We do this all day in programming, we give a complex
component a name and it means a lot more then just the
actual word. The problem is that this specific meaning is
often not universal, it's contextual.
If you take a hammer, an integer and design patterns, the
latter is the least universal thing. They depend on domain,
context and conventions, and can change quite a lot
depending on the language. Removing hammers and integers
from the world would cause collapse, removing design
patterns would do almost nothing.
I guess the active celebration of design patterns as a
catalogue of general wisdom is my primary issue here. I'd
welcome any project/team/company that maintains a catalogue
of their individual "patterns". But a universal source of
truth has too much bible flavor to me. (Oh it also dictates
OOP by default which renders it's inherent "wisdom"
completely useless in many languages)
palata wrote 17 hours 58 min ago:
I feel like we're talking past each other. I tend to
agree with you, I don't like having a "bible" and
"celebration of design patterns as a catalogue of general
wisdom".
But formalising concepts with words makes sense. If your
company maintains a catalogue of their patterns, and
someone happens to know that this specific pattern is
usually called a "singleton", I would find it weird to
call it a tomato.
Some patterns have different names in different contexts
or languages, and that's fine. I don't find it weird to
have a discussion around "in this language there is this
pattern that they call X, does that ring a bell for you
working on that other language? The idea is [...]", and
maybe the answer is "yep we have it too" or "oh, we call
that Y, but that's pretty similar".
Yokohiii wrote 16 hours 26 min ago:
Well I guess I am not clear enough. Naming stuff is a
normal human habit, maybe even why we have language? So
we can agree on that, it's helpful.
But you say it yourself, a thing is called different in
another language, so the thing is bigger then the word.
But everyone can handle it better in his own head and
in communication with a word for it.
I guess my usual grief is that any kind of excessive
celebration and ceremony comes down to some kind of
brainwash. Which mostly affects newbies and cultists.
The article for example isn't overtly critical on
singletons, while past design pattern writings often
heavily disregarded the use of it. So we don't just
always reiterate the good, but also the bad.
palata wrote 9 hours 44 min ago:
I don't mind the celebration and ceremony as long as
they don't bother me personally. I wouldn't fight
against the existance of a PatternConf, I just
wouldn't go :-).
I've had some debates with junior devs who really
wanted to enforce their newly-learned patterns, and
my experience there is that passed a certain point,
there is no convincing anymore: if they really insist
about overengineering something with their
newly-learned concept and the hierarchy doesn't allow
me to prevent them from doing it, anyway they will do
it. So instead of fighting I just let them, and if it
turns out to be a waste of time in the end... well
that's not my problem: I was not in a position to
prevent it in the first place.
It's not only patterns though: some juniors have a
way to try to use every exciting framework or library
or tool they just discovered.
Yokohiii wrote 2 hours 37 min ago:
The silly thing is that I've been the same when I
started. A high energy kid playing around and
celebrating everything fresh and new, with a big
ego.
Probably a bad habit trying to stop them, they need
to learn walking before they can sprint. The
question is always how to put limits on them? I say
it's overengineered, they say it's modern code and
I am old. So what do you do if they send you a PR
that is just plain wrong? I mean it seems like you
delay the conflict from upfront design/planning to
pull requests.
svilen_dobrev wrote 1 day ago:
the actual software design patterns, unbiased by
language/particular-usage, are subtle. i would go as far as say that
there are also "design-patterns"-usage patterns.. and those might be
even more subtle. e.g. what is/constitutes "interpreter", and when to
use one, and when/if one is being used behind-the-scenes. Sometimes
it is a single piece that is easily pinpointable. Sometimes a whole
(sub)system behaves like one (e.g. event-sourcing stuff) but it's not
easily cut into this is this, that is that.
But anyway, this site seems javascript/frontend wanna-bees oriented..
please don't take those tutorials as mantras-to-follow-at-any-rate.
See if you can take the knowledge and move on.
A very good book, besides the GoF one, is the "Organisational
patterns book by James Coplien, Neil Harrison" [1]. It contains some
of the GoF *plus* all the non-technical ones, and they are bundled
together - as software making is not just the coding.. i have the
list of those patterns essences (patlets) extracted, here the link -
[1] edit: it's from ~2003-5 and images are missing. May need to scan
them from the book. Closest i found is [2], at least to get some idea
[1] [2]
(HTM) [1]: https://www.svilendobrev.com/rabota/orgpat/OrgPatterns-patle...
(HTM) [2]: http://www.amazon.com/exec/obidos/tg/detail/-/0131467409/
(HTM) [3]: https://www.scrumbook.org/book-outline/history-of-the-patter...
agumonkey wrote 1 day ago:
What about the social / communication aspect ? Having a common
vocabulary of pattern may help reduce cognitive load when reading
others code. Just a soft opinion because I assume it's the reason
frameworks and conventions help teamwork. Less per-context custom
solutions.
zelphirkalt wrote 23 hours 1 min ago:
It really depends. If under the guise of "best practices" and
"patterns" a team creates an unmaintainable, not easily extensible
mess, then all this community aspect was good for exactly nothing
but shoulder patting. If instead pattern are used sparingly, where
they actually make sense, then sure, it can help.
We need to keep in mind, that the most composable concept in
computer programming is the pure function (or maybe a mathematical
"relation", if we want to abstract further). Not a mutating object.
Not some constellation of objects that constitutes a pattern. Those
are merely special cases.
I am currently developing a GUI application. Most of the classes in
my code are classes, that are custom widgets. The GUI framework is
OOP, so that is kind of infectious for the rest of the code. Still
I try to keep some stuff separately as pure functions. Probably
will outsource more stuff like that into completely self sufficient
functions. The only pattern I have so far in the whole application,
is a mediator, which I use as a way to have objects register
themselves as listeners to specific events and for other objects to
send these events to anyone who will listen. That way objects don't
need to know, which other objects are interested in learning about
some event. Could I have built in some factories and whatnot?
Surely I could have, but there would have been very little, if any
benefit. Even the mediator only exists, because the GUI framework
does not have a way to send events that include data, so I need a
way to do that. Otherwise I could even get rid of that pattern as
well.
In this way pattern are useful for when you really need them, but
these OOP pattern by themselves, without context, don't really have
a value. No code becomes better by building in more patterns,
unless the situation requires such a solution.
hyfgfh wrote 1 day ago:
Agreed! The problem is that some 'seniors' never cared to learn
patterns in the first place. Thatâs a huge problem for frontend,
where we have increasingly complex architectures and people with very
little experience with design.
Even some principles aren't known. I always recommend the book Head
First: Design Patterns. It's in Java, but the lessons can be applied
in every language.
Unfortunately, we are in a 'post-knowledge' era... I don't know how
we can keep things up at this pace.
signal11 wrote 1 day ago:
Design patterns are language independent, but a lot of the ones
many Java devs focus on are a bit meh.
In a world with only assembly language, for instance, itâs a bit
like making a big deal about a âguarded repetitionâ pattern
(aka a while loop).
Eg in Lisps, a lot of patterns become one-liners. At that point
these patterns become a âcan you write decent Lispâ question[1]
(HTM) [1]: https://mishadoff.com/blog/clojure-design-patterns/
Kwpolska wrote 1 day ago:
I've read that book, and it felt very childish and condescending.
Design patterns cannot be applied in every language. While some
patterns are applicable everywhere, many of them provide
replacements for missing language features. For example, the
Builder pattern is not very useful in languages with default
parameters and named arguments.
microtherion wrote 1 day ago:
I'm not sure what Builder would have to do with default
parameters and named arguments.
Builder is extremely useful to pair with a parser, e.g. SAX. The
parser parses the input, and the builder then decides what to do
with it.
Kwpolska wrote 23 hours 48 min ago:
Here is an example of the Builder pattern that illustrates my
point: [1] Letâs remove the category argument and you get
this:
Post post = new Post.Builder()
.title("Java Builder Pattern")
.text("Explaining how to implement the Builder Pattern in
Java")
.build();
This builder is a more readable alternative to this:
Post post = new Post("Java Builder Pattern", "Explaining
how to implement the Builder Pattern in Java", null);
But if Java supported named arguments and default values (the
default would be null), this could just be:
Post post = new Post(title: "Java Builder Pattern", text:
"Explaining how to implement the Builder Pattern in Java");
(HTM) [1]: https://www.baeldung.com/java-builder-pattern#bd-class...
vips7L wrote 20 hours 17 min ago:
Funny part is that Java does have named parameters, but only
for annotations!
davidkunz wrote 1 day ago:
> It's in Java, but the lessons can be applied in every language.
I can only discourage anyone from applying Java patterns all over
the place. One example in JavaScript: There was a functionality
that required some parameters with default values. The plain
solution would have been:
function doStuff({ x = 9, y = 10 } = {}) { ... }
Instead, they created a class with private properties and used the
builder pattern to set them. Totally unnecessary.
prodigycorp wrote 1 day ago:
What's interesting about frontend is that there are two ways to
evaluate it: by how it looks and how it's written.
It definitely biases how people evaluate llms. Many cite Claude as
their favorite llm for generating frontend code, but I suspect that
many people prefer it because the output is prettier, rather than
better composed.
zwnow wrote 1 day ago:
For webdev especially everything I do is basically singletons...
For UI state management its just perfect and that's about the hardest
thing in web dev. Also easy to recover state with, in a SPA if a user
refreshes the site. Or control whether a modal is open or not. Easy
to centralize logic too... Never looked into any other patterns as a
lot of them seem like bloat.
crabmusket wrote 1 day ago:
This is a nicely laid out collection of tutorials, but I'm sad that
collections like this have drifted away from the very deliberate
structure that A Pattern Language introduced. While patterns weren't
invented by Alexander and co, they did inspire a lot of what we see in
tech these days, inherited via design patterns etc.
In A Pattern Language, each pattern is hyperlinked to other patterns in
a kind of hierarchy, where larger patterns (like "house cluster") are
broken down into smaller constituent parts ("main entrance") all the
way to quite granular details ("low doorway").
This is because you can't just take a pattern on its own; it forms part
of a larger whole.
Tech pattern books often focus on small recurring structures (e.g.
"command pattern" from this site), but not how they help create some
larger pattern, or in the other direction, what are the smaller
patterns that help create them.
This sounds like a lot of hard work of course, which is why people
don't do it.* I would love to see this accomplished though. If only I
had an extra 36 hours in each day.
One thing that A Pattern Language is also great at is motivating each
pattern with a specific problem or symptom. This site seems to do a
decent job at that, though some problems seem... kind of weakly
motivated. For example, the above mentioned "command pattern" is
motivated by "what if we need to rename a method?" which... is pretty
weak tbh.
*EDIT: also because fitting patterns into a whole, maybe unavoidably,
will promote a perspective, or a way of building a whole system. A
pattern book for web applications written from an HTMX point of view
would be a very different book to one written from a React slant. Maybe
one pattern language can accommodate both sets of technologies, or
maybe not.
spopejoy wrote 15 hours 58 min ago:
If you're trying to connect Alexander to software patterns like GOF,
it's important to include Gabriel's "Patterns of Software" [1] as the
first genuine attempt to apply Alexandrian patterns to software. It
also introduces the first and probably the best takedown of OO
inheritance as not reuse but instead a form of _compression_ that is
in many ways worse than just copy-and-paste.
1 -
(HTM) [1]: https://www.dreamsongs.com/Files/PatternsOfSoftware.pdf
crabmusket wrote 15 hours 7 min ago:
This looks great! I am diving right into the yak of producing a
HTML version of this.
crabmusket wrote 1 day ago:
Here's an excerpt from APL showing what I mean about the connections
to the other patterns. This isn't the whole pattern, there's a lot
between the problem statement and summary. Annotations in brackets
are mine.
---
Short Passages (132)
[Context, or pre-links]
The Flow Through Rooms (131) describes the generosity of light and
movement in the way that rooms connect to one another and recommends
against the use of passages. But when there has to be a passage in an
office or a house and when it is too small to be a Building
Thoroughfare (101), it must be treated very specially, as if it were
itself a room. This pattern gives the character of these smallest
passages, and so completes the circulation system laid down by
Circulation Realms (98) and Building Thoroughfare (101) and The Flow
Through Rooms (131).
[Problem statement]
Long, sterile corridors set the scene for everything bad about modern
architecture. In fact, the ugly long repetitive corridors of the
machine age have so far infected the word "corridor" that it is hard
to imagine that a corridor could ever be a place of beauty, a moment
in your passage from room to room, which means as much as all the
moments you spend in the rooms themselves.
[Pattern contents here]
[Pattern summary]
Keep passages short. Make them as much like rooms as possible, with
carpets or wood on the floor, furniture, bookshelves, beautiful
windows. Make them generous in shape, and always give them plenty of
light; the best corridors and passages of all are those which have
windows along an entire wall.
[Elaboration, or post-links]
Put in windows, bookshelves, and furnishings to make them as much
like actual rooms as possible, with alcoves, seats along the edge -
Light on Two Sides of Every Room (159), Alcoves (179), Window Place
(180), Thick Walls (197), Closets Between Rooms (198); open up the
long side into the garden or out onto balconies - Outdoor Room (163),
Gallery Surround (166), Low Sill (222). Make interior windows between
the passage and the rooms which open off it - Interior Windows(194),
Solid Doors With Glass(237). And finally, for the shape of the
passages, in detail, start with The Shape of Indoor Space (191)
Simplita wrote 1 day ago:
This resource aged surprisingly well. Still one of the clearest ways to
understand common frontend patterns.
akst wrote 1 day ago:
A singleton for me is just making sure you define a single instance of
something at the entry point of your app and passing it down via
constructor arguments, which is normally what I do.
I understand you can override modules in tests, and if you have a
version of your app that runs in a different environment where you
might replace a HTTP service with a different variant (like if an RPC
service that normally performs HTTP requests, but in one case maybe you
want to talk to specific process, worker or window using message
passing).
I really really feel using constructor args is just a lot simpler in
most cases. But I think there's a reason why people don't always do
this:
1. Sometimes someone is using a framework that imposes a high level of
inversion of control where you don't get to control how your
dependencies are initialised.
2. (this was me when I was much younger) Someone dogmatically avoided
using classes and thought they could get away with just data and
functions, and then they realise there is some value in some shared
instance of something and then they just undermine any functional
purity. Don't get me wrong, functional purity is great, but there are
parts of your apps that just aren't going to be functionally pure. And
you don't need to go full OOP when you use classes.
----------------------------------------
Here are some examples of what I mean.
Here's one example, where I have an app defined in web components and I
define the components for each part of the app before passing them into
the skeleton. It's a more simple app and I avoid some shared state by
different landmark components communicating by events. [1]
----------------------------------------
Here's another example, this app is built of multiple command line
instructions that sometimes have their own version of services
(singletons) with specific configuration, sometimes they are
initialised in child processes. [2] Because this app is doing a lot of
scrapeing and I wanted to also child worker processes to do their own
HTTP I was going to make a variant of my HTTP service which talked to a
daemon process that tracked state for open connections to specific
domains to avoid opening too many simultaneously and getting blocked by
that host.
Updating the code that uses HTTP will be effortless, because it will
continue to conform to the same API. I know this because I've already
done this multiple times with HTTP scrapping in the app.
(HTM) [1]: https://github.com/AKST/analysis-notebook/blob/b3f082fc63c9bdf...
(HTM) [2]: https://github.com/AKST/Aus-Land-Data-ETL/blob/672280a8ded69a5...
(HTM) [3]: https://github.com/AKST/Aus-Land-Data-ETL/blob/672280a8ded69a5...
phplovesong wrote 1 day ago:
When overused these kind of "patterns" always lead to slow and hard to
grasp code that is a nightmare to maintain.
FieryMechanic wrote 1 day ago:
Like many things they shine when use appropriately.
z3t4 wrote 1 day ago:
My experience is that they are best discovered independently as a way
to abstract code, and let them come naturally to solve a problem. So
for most things in Dev, if you do something prematurely you might end
up with a good solution for a non existing problem.
oleggromov wrote 1 day ago:
Or, even more likely, a bad solution for a non-existent problem.
noveltyaccount wrote 1 day ago:
In my senior year of college two decades ago, I needed one or two
credit hours to finish up, and I signed up for a once per week software
patents (as in, intellectual property, I thought) course. It turned out
to be a patterns course taught by none other than Ralph Johnson and the
text was his famous Gang of Four Design Patterns book. Happy accident,
it turned out to be among the most professionally useful courses I ever
took.
(HTM) [1]: https://en.wikipedia.org/wiki/Ralph_Johnson_(computer_scientis...
wavemode wrote 1 day ago:
Great site!
I tend to advocate for people to study design patterns. Not for the
purpose that you will necessarily ever use most (or even any) of these
exact patterns in your software, but just that you've strengthened your
mental muscle for software design in general. I encounter lots of
engineers who simply aren't able to think "outside the box" when
building something new.
lock1 wrote 1 day ago:
I always wondered if people actually find it beneficial to follow
these "design patterns" or not.
Personally, I prefer to learn FP patterns, which tend to be backed
with nice mathematical properties behind them.
fiddlerwoaroof wrote 1 day ago:
I wish people would stop promoting the singleton pattern: in almost
every case Iâve seen, singletons are unnecessary tech debt and solve
a problem thatâs better solved with some form of dependency injection
(and I donât mean the XML/YAML monstrosities various frameworks force
on you but rather constructor arguments or factory functions)
gm678 wrote 1 day ago:
Yes, I have to admit my interest was piqued by the banner, and I then
scrolled down, saw the first example was singletons, and closed the
tab.
dkersten wrote 1 day ago:
Singletons are globals and should be treated the same as every other
global (that is, used sparingly and with care).
Worse is that singletons enfurece a single instance which is almost
always unnecessary. Itâs trivial to only create as many instances
as you need.
hokumguru wrote 1 day ago:
Off the top of my head, rails (currentattributes), Laravel (facades)
especially, and most iOS apps use singletons quite well. Itâs all
in moderation and depends highly on how itâs used, much like every
other design pattern.
I think people just donât like Singletons because theyâve been
especially misused in the past but I guarantee the same argument
stands for any other design pattern.
deaux wrote 1 day ago:
Why pose DI as replacing singletons when they're used together all
the time? Injecting dependencies to create a singleton repository or
service class, which is shared across requests.
HumanOstrich wrote 1 day ago:
The site is not "promoting" the singleton pattern. In fact, there is
a "Tradeoffs"[1] section that calls it an anti-pattern in JavaScript.
In spite of that, there are plenty of reasonable use cases for
singletons in many languages, including JavaScript. For example, ES
Modules are effectively singletons. If you import the same module in
multiple places, it only gets evaluated once.
Let's not turn the singleton pattern into forbidden knowledge.
[1]
(HTM) [1]: https://www.patterns.dev/vanilla/singleton-pattern/#tradeoff...
nl wrote 1 day ago:
Does anyone remember the Yahoo design patterns library? It was mostly
for UX pattern (eg: ways to "Rate an object") and it was really good.
Almost 20 years ago.. damn. [1] [2] They had a great comparison of the
different behaviors leaderboards could encourage in users.
(HTM) [1]: https://creativecommons.org/2006/02/14/yahoodesignpatternlibra...
(HTM) [2]: https://web.archive.org/web/20060221111812/http://developer.ya...
dimaor wrote 1 day ago:
for some reason I remember him being related to YUI, but I learned JS
from Douglas Crockford, one of the best lectures from the old days of
JS.
dahcryn wrote 1 day ago:
we often forget how great Yahoo engineering was back in the day, sad
it was destroyed by bad management and horrible business cases
prioritization
no_wizard wrote 1 day ago:
YUI was ahead of its time as well
cachius wrote 1 day ago:
And it spawned ExtJS.
Which could have been React, but they messed up.
Literally they built a faster Facebook app 'Fastbook' in 2012.
Short history lesson: [1] In August 2006, a guy by the name of Jack
Slocum (now CEO of Alta5) began to blog of his experiments with
YUI. Over time, these experiments became more complex and Jack
would start to bundle them into what would later be named YUI-ext
(Yahoo UI extensions) â the precursor to Ext JS (Extensible
JavaScript).
Jack Slocumâs blog was used to communicate his vision for YUI-ext
and garnered community support from around the world.
The release of the Grid component for YUI-ext would forever change
the trajectory of the library and the community as the GridPanel
would become the core UI component for many applications to come.
Throughout its early life, Jack continued to build upon YUI-ext by
adding features to the framework, such as animations, Modals, Tab
Panel, Resizable elements and a layout manager that greatly
expanded upon the YUI framework. These components would seldom
extend the YUI library and had their own rendering functions.
YUI-ext created a foundation for web programmers unlike anything
the world had seen before and many developers flocked to the
framework and invested in the newly formed community. The net
result was the explosive expansion of YUI-ext.
From YUI-ext to Ext JS
In January 2007 we found Jack extremely busy to push out YUI-ext
0.40 and it is this version where we find the namespace of the
framework change from YAHOO.ext to a much simpler Ext (pronounced
âekst J Sâ or âE-X-T J Sâ by some of us old-school
community members).
February 2007, Ext JS 1.0 was being developed in tandem with a new
website, ExtJS.com. In April 2007, the launch of ExtJS.com was
announced to the community along with the release of Ext JS 1.0.
[2] For those that donât know, Ext JS was one of the first
JavaScript frameworks in the early days of Web 2.0. It was the
first framework to offer a complete package of everything needed to
build full-fledged applications using just JavaScript in a web
browser. At one point, it was used by over 2 million developers
worldwide, 70% of the fortune 500, and 8 of the top 10 financial
institutions. It was years ahead of everyone else, open source, and
had an incredible community of passionate people contributing to
its success.
As that success grew, so did the number of copycat competitors.
They eventually started taking the code and assets and embedding
them into their own frameworks. Adobe embedded it in Cold Fusion
and other competitive frameworks followed their lead without any
contribution to the framework or community.
At the time the thought of competing directly against a behemoth
like Adobe was scary. How could they take our product and offer it
as their own? I took what I thought was the right action to
âprotectâ Ext JS from being âstolenâ by changing to a more
restrictive license. That was a huge mistake.
Looking back in hindsight, without the fear, I have a much clearer
picture. I see what truly made Ext JS great was not the code - it
was all the people who loved, contributed and supported it. As we
worked on making our own dreams a reality, we helped others do the
same, sharing our knowledge, code, and solving tough challenges
together.
That is what really mattered â our community. That is what I
should have protected, not the code. You were my closest friends. I
am sorry I changed the license after we all came to an agreement on
the first license. That was a breach of integrity and you deserved
better. I would do it differently if I could.
(HTM) [1]: https://medium.com/hackernoon/the-rise-and-fall-of-ext-js-...
(HTM) [2]: https://web.archive.org/web/20230222210535/https://jackslo...
paulirish wrote 1 day ago:
Amen! The terms "accordion" and "carousel" were really codified by
the pattern library. Establishing a common vernacular definitely
accelerates things.
culi wrote 1 day ago:
Not quite the same thing, but there's this incredible (open source)
project called The Component Gallery that is basically just a
repository of UI components across 93 (currently) different design
systems. It's an incredible resource if you're building a component
from scratch and either want some design inspo or technical advice.
Many of the design systems have thorough guidelines for a11y/ARIA
best practices that I've learned a ton from
(HTM) [1]: https://component.gallery/
101008 wrote 1 day ago:
Oh, the second link is amazing. I love the old web, and that brought
a lot of nostalgia.
vivzkestrel wrote 1 day ago:
fantastic resource! kindly add svelte design patterns too and sveltekit
if you can
android521 wrote 1 day ago:
The ones that actually match POSD (deep modules, small interfaces,
lower complexity) and work great with plain functions are:
Module Pattern
Factory Pattern (factory functions)
Mediator / Middleware Pattern (as function pipelines)
Hooks Pattern (custom hooks, generalized)
Container / Presentational Pattern (implemented with function
components + hooks)
Everything else is either neutral, UI-only, or fights POSD (Singleton,
Mixin, etc.).
Patterns from that page you should treat skeptically for POSD
From Patterns.dev, for your POSD-style codebase Iâd avoid or
downplay:
Singleton Pattern â encourages global state and tight coupling.
Patterns
Mixin Pattern â tends to increase interface surface and make
dependencies opaque.
Patterns
Observer Pattern â powerful, but event-based wiring can obscure data
flow and increase âsystem complexityâ (classic POSD warning).
Patterns
neogodless wrote 1 day ago:
What does POSD stand for?
jakubmazanec wrote 1 day ago:
I'm assuming John Ousterhout's book A Philosophy of Software Design
[1], which I would recommend reading before reading about design
patterns, because it's more fundamental.
(HTM) [1]: https://news.ycombinator.com/item?id=37975558
culi wrote 1 day ago:
I'm assuming Philosophy of Software Design but I've never seen
anyone blatantly presume it's an implicit initialism
8cvor6j844qw_d6 wrote 1 day ago:
Looks great, time to add it to my bookmarks.
Anyone has other sites like these to share?
- Domain-driven design, design patterns, and antipatterns [1] -
Refactoring and Design Patterns [2] - Standard Patterns in Choice-Based
Games
(HTM) [1]: https://deviq.com/
(HTM) [2]: https://refactoring.guru/
(HTM) [3]: https://heterogenoustasks.wordpress.com/2015/01/26/standard-pa...
slig wrote 23 hours 20 min ago:
(HTM) [1]: https://www.deceptive.design/
elktown wrote 1 day ago:
Here be dragons. People trying to pattern-match their problems to
design patterns can waste a lot of time and effort over many years.
Use responsibly.
gopher_space wrote 23 hours 0 min ago:
To your point, everything we do is context-sensitive and patterns
are revealed by abstracting context.
endymion-light wrote 1 day ago:
+1 for refactoring.guru, find it really useful whenever i want to
refactor some pre-existing code. Only wish they had a physical book!
esfandia wrote 1 day ago:
The OG site for patterns is of course the Portland Pattern
Repository. I believe Ward Cunningham invented wiki for this purpose
initially!
(HTM) [1]: https://c2.com/ppr/
begueradj wrote 1 day ago:
Useful links. Thank you.
bbminner wrote 1 day ago:
I think it is difficult to oversell the bob nystrom game patterns
book
(HTM) [1]: https://gameprogrammingpatterns.com/contents.html
crabmusket wrote 1 day ago:
Microsoft's cloud design patterns are quite well-written IMO, if
you're into that kind of thing
(HTM) [1]: https://learn.microsoft.com/en-us/azure/architecture/pattern...
culi wrote 1 day ago:
Oh here's a resource for common "idioms" across programming languages
(HTM) [1]: https://programming-idioms.org/
culi wrote 1 day ago:
I posted this elsewhere in this thread: [1] Great meta resource for
building UI components.
(HTM) [1]: https://component.gallery/
lelandfe wrote 1 day ago:
Design patterns and component libraries are a bit related but
they're pretty different concerns ultimately.
culi wrote 21 hours 57 min ago:
It's more of a meta resource. Many of these design guidelines go
in depth on accessibility best practices and UI patterns
sdovan1 wrote 1 day ago:
- Java Design Patterns
(HTM) [1]: https://java-design-patterns.com/
vips7L wrote 1 day ago:
Love how you were downvoted for mentioning Java.
mdhb wrote 1 day ago:
The JS community is so freaking strange sometimes.
rambleraptor wrote 1 day ago:
Iâll make a plug for aep.dev, which is a collection of API design
best practices and assorted tooling
JimDabell wrote 1 day ago:
Google has something similar:
(HTM) [1]: https://google.aip.dev
rambleraptor wrote 1 day ago:
AEP began its life as a fork of AIP! Weâve got a bunch of
ex-Google folks on the project, including the former API Lead at
Google.
seabass wrote 1 day ago:
Love this! Just wanted to note that I think thereâs a mistake on the
flyweight pattern pageâs example. Youâre using getting a boolean
with Set.has but treating it like a Book (as if you had used Set.get).
I also donât really understand how this saves memory if youâre
spreading the result into a new object, but maybe someone here can
enlighten me!
seabass wrote 1 day ago:
Ah I think I understand now. The return type of createBook is true |
Book, which is likely a mistake, but happens to work because when you
attempt to spread a boolean into an object it removes itself. But if
you were to edit the example to have a stable return type of Book
then it would no longer save memory, so perhaps that was intentional?
HumanOstrich wrote 1 day ago:
I was glancing around and landed on the page for the flyweight
pattern.[1]
It looks like `addBook` is using the spread operator, which always
creates a shallow copy of the book instance properties, thus nullifying
any benefits of the flyweight pattern. It also attaches extra arbitrary
properties, but still assigns the result to a `book` variable. I don't
think this is a great example.
[1] Edit: I forgot to give you kudos for all the effort it must have
taken to create all this content, and I appreciate that you're making
it available for free.
(HTM) [1]: https://www.patterns.dev/vanilla/flyweight-pattern/
songodongo wrote 1 day ago:
Good to know I wasnât the only one thinking âwait a secondâ¦â
when reading that one and seeing the spread operator being used.
KPGv2 wrote 1 day ago:
> which always creates a shallow copy of the book instance
properties, thus nullifying any benefits of the flyweight pattern
No, the opposite: it highlights the benefits of the flyweight
pattern. The shallow copy saves memory. That's the point. You have
two identical books. Rather than wasting memory with a deep copy, you
make a shallow copy, where all your props point to locations in
memory where values are located, and then you modify whatever is
different. Now your shallow copy only consumes a small bit of extra
memory.
And if those props are all primitives, then you can then modify that
shallow copy, and it won't affect the original.
HumanOstrich wrote 1 day ago:
The point is to not make a copy at all for the shared data of the
same book. That's even what the page claims is happening (but it's
wrong). That's the whole point of the flyweight pattern[1].
Instead, the example returns the same book instance for the same
isbn in `createBook`, then blindly copies the shared data like
title, author, and isbn every time in `addBook` to a new object.
> The shallow copy saves memory....
Versus not making a copy? A shallow copy of primitives still copies
them and uses additional memory. Maybe there's some low-level
optimization that makes it more efficient than that, but it's not
relevant here. And there isn't any deep cloning happening in the
example.
Might as well get rid of the complexity and instantiate a new Book
class every time. And maybe stop shallow-copying class instances
into new plain objects. It works for the example but has footguns.
Conveniently, there are other patterns on the site that would help
you avoid creating an amalgamation of random merged class instances
and objects.
The whole example is a mess.
[1]
(HTM) [1]: https://en.wikipedia.org/wiki/Flyweight_pattern
1970-01-01 wrote 1 day ago:
Thanks, I was looking for something just like this today!
(DIR) <- back to front page