
Design patterns for hacking together prototypes: object dictionaries - azhenley
http://web.eecs.utk.edu/~azh/blog/objectdictionaries.html
======
ratww
Hah, this reminds me a lot of ECS (Entity-Component-System) architectures [1]

The first time I read about ECS I thought it was a completely crazy idea, but
after trying it I realized that I was able to have extreme low-coupling and
complete separation of concerns. It was great for hacking things, but in the
long term it was also great for maintenance and code reuse! I never felt this
way about OOP, ever.

In this case however it seems that the "Entity Management" part is ad-hoc,
with Editors themselves putting things on the dictionaries. Ooops :)

EDIT: I think one can get a lot of mileage out of something like this if the
dictionary management code is properly encapsulated in an isolated
module/class. Just an idea.

[1]
[https://en.wikipedia.org/wiki/Entity_component_system](https://en.wikipedia.org/wiki/Entity_component_system)

~~~
TeMPOraL
ECS is a hodge-podge of concepts, each implementation mixing in different
proportions some or all of the following: relational data model, data-oriented
architecture, flexible recombination at runtime, removing the fixed
inheritance graph, cache-friendly flow.

What's in the article is really closer to "relational data model" than all of
these above. All these dictionaries are essentially implementing SQL selects.
The "relational data model" lens to viewing ECS is that it's essentially
giving each component its own table, and doing plenty of joins.

I find this really interesting, and my current side project is a roguelike
game that focuses _only_ on that part - relegating all game ECS into an in-
memory SQLite database. I decided to go that way after trying to improve my
last attempt at an ECS framework, only to realize I'm essentially hand-coding
SQL indexes, and that's not something I want to do when I'm prototyping a
game.

~~~
atroche
That's very cool. It reminds me of a game someone built with DataScript (an
in-memory relational data store based on Datomic):
[http://www.zetawar.com/blog/2016/05/17/technology-
choices/](http://www.zetawar.com/blog/2016/05/17/technology-choices/)

------
meddlepal
And then before you know it your prototype is in production, you've been
promoted or left the company, and it is some poor bastard that you've never
mets problem!

~~~
azhenley
I'm going to quote this in my lecture tomorrow to my undergraduate software
engineering class :)

------
fuball63
I understand this is for rapid prototyping and not for production use, as the
author clearly stated. But it did remind me of an anti-pattern I see all the
time at work that does make it's way into production, often for the same
reason.

I work primarily in Python, and one thing I see all the time is using
dictionaries instead of method arguments. The thought is that when the method
evolves over time, you can just add a field to the dictionary. What ends up
happening is this dictionary argument is passed up and down the call stack for
every nested method call, and sometimes elements are added, edited, or deleted
on the way.

Whenever I have to do a refactor of methods like this, it is awful trying to
figure out the state of the dictionary, what was originally supposed to be in
it, and if it's returned, which parts are actually relevant.

~~~
YawningAngel
Wouldn't it be much more appropriate to use immutable dictionaries in this
case (or just not mutate them by convention)? Clojure does this and it seems
to work pretty well.

~~~
fuball63
Yes but at that point, designing the structure of the dictionary and not
allowing any down-stream method calls to alter it would require the same
amount of work/forethought as actually redesigning the method to take X
defined inputs and return Y values (and documenting it).

~~~
pdimitar
Initial effort when refactoring might be the same -- or even bigger -- but it
will save you time afterwards. The added peace of mind is not to be
underestimated either.

------
oweiler
Did this in a Groovy project once. It indeed allowed me to move faster in the
beginning but refactoring the project half a year later was the horror.

------
jlangemeier
This is my default python design pattern for quick projects. Just treat
everything like a dictionary, EVERYTHING.

~~~
jayd16
Well, to be fair that's almost just idiomatic python.

~~~
carapace
Yeah, in Python everything _is_ a dictionary: namespaces, classes, instances.
;-P

------
contingencies
Why not just _ln -s ..._ ? In the same spirit of thinking...

 _Those who don 't understand Unix are condemned to reinvent it, poorly._ \-
Henry Spencer

... via
[https://github.com/globalcitizen/taoup](https://github.com/globalcitizen/taoup)

~~~
jacobush
Yeah. Like how systemd is inner-platform-ing [0] the hell out of Linux.

[0]

[https://en.wikipedia.org/wiki/Inner-
platform_effect](https://en.wikipedia.org/wiki/Inner-platform_effect)

------
jayd16
So...fields, then? Except with a leaky scope and no encapsulation?

This can be useful when you want to keep an association to an object but you
want to ownership of that list of associations in a different object but I
certainly would not make these global.

------
aasasd
As a backend guy, what I see is that I could assign an id to each editor and
reference everything by the id. It's about the same thing internally, of
course, but a bit more orthodox for those weirded out by objects as dictionary
keys. Plus I'd probably have the file path and such on the editor object, then
only labels and buttons outside the editor would be kept out of the editor
objects. Voila, a pretty classical architecture.

------
keyle
This seems like absolutely horrible advice. Building something quickly doesn't
mean disregarding every development common sense since we invented these
things to help us.

What's next? Forget numbers, just String everything because you'll save time
serializing?

~~~
azhenley
Oh, it’ll get worse! Just wait until pattern #3 that I post.

~~~
codesushi42
This is exactly why you work in academia.

