

Getters, Setters, and Class Decorators in ES 6 - lx
http://raganwald.com/2015/08/24/ready-get-set-go.html

======
dustingetz
One repeated theme in this article is that `currentUser.id = 42` is _bad_ and
`currentUser.setId(42)` is _good_ because it helps us organize our code (here
are some quotes FTA[1]). Then the article builds up some complicated
metaprogramming thing to turn the former into the latter. (Poe's law?)

BUT! Compare to the React.js way of doing things. React.js encourages us to
store our models in plain old javascript data, e.g. nested JSON-y blobs, not
encapsulated by classes and methods, you don't have getters, and setters have
major limitations. Yet we can still separate concerns, re-rendering can still
be organized to the right place, we can still log updates and cleanly
validate. Without subclassing, or writing change callbacks, or resorting to
metaprogramming. (Hasn't J2EE and Rails taught us that metaprogramming leads
to really complicated systems? Also React.js is just an example, there are
other systems where we access data directly)

I don't think it's direct property access that's the problem, but rather,
mutability.

[1] "There was no way to decorate such operations with cross-cutting concerns
like logging or validation"

[1] "Direct access does not allow you to organize the functionality associated
with getting and setting properties, it forces the code doing the getting and
setting to also be responsible for anything else associated with getting and
setting."

[1] "Whereas we can’t do anything like that with direct property access.
Mediating property access with methods is more flexible than directly
accessing properties, and this allows us to organize our program and
distribute responsibility properly."

~~~
asolove
I think the "React.js way" through a Flux flow takes this idea even farther.
Now, instead of an individual object being allowed to change itself, we go
through an even greater indirection, firing an abstract action and letting a
store figure out how to make changes to the appropriate data.

The real question is: if our data has real validation and invariants, who
maintains them?

\- Does every piece of code that might change one attribute have to worry
about it?

\- Do individual objects protect themselves through methods and take
responsibility?

\- Or does a whole managed context take responsibility, allowing it to
guarantee invariants about groups of objects together?

Experience tells us the first option quickly becomes problematic. The second
certainly works, but requires discipline in how you design objects (the origin
of many of the DDD patterns). The third is less widely used, seems to work
better, but has some overhead. But don't kid yourself that it's less
indirection/metaprogramming. It's more.

~~~
dustingetz
Great post, I'm gonna take this off topic now because I've been thinking a lot
about this and curious your thought:

> we go through an even greater indirection, firing an abstract action and
> letting a store figure out how to make changes to the appropriate data

Can't this indirection just be modeled as a function? Instead of firing an
action we call a function, which returns the appropriate state updates. No
metaprogramming, and composable when used with cursor pattern to run the
actual state update effect. (ActionStoreDispatcher flux doesn't compose)

~~~
asolove
Yeah!

(You probably know about this but others may not.) I like Elm's architecture,
which has typed update functions that can be nested. This makes the full stack
of the component composable and is something like a cursor:
[https://gist.github.com/evancz/2b2ba366cae1887fe621](https://gist.github.com/evancz/2b2ba366cae1887fe621)

