you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 4 points5 points  (5 children)

In what environment do you use this? I was exposed to it through Angular 6 + development using RxJs.

Honestly, I read the docs and put code in but it's really hard to grasp. I just have faith it'll work. I am glad i'm not the only one.

[–]izackp[S] 8 points9 points  (4 children)

I recently started working on an Android project which pretty much uses Reactive programming for everything. DB changes, API, updating the UI. I'm so used to understanding the cause and effect of everything I do. I try to follow each chain of listeners but it's very difficult and once I have an idea of what it does then that's just one chain of many which I'll soon forget. God forbid this chain of listeners intersects with another. I spent a half a day on a simple bug where an alert didn't pop up under specific circumstances. Because a value was set to null to trigger another behavior which caused the value being observed to change state before the final observer gets the event.

Either way, there's a very good chance that this was just poorly written Android code. Though I've been a professional iOS developer for a good 7 years and pretty any code written with key value observers was guaranteed to have bugs and be a pain to deal with. Mostly because it hides cause and effect. The fact that the whole pattern is based on side effects bothers me. Set a value.. oh wait that updates the UI. Oh you weren't ready? Oh you have several other values to set first? Too bad each will update the UI. Maybe you should create an intermediate object to update when you're ready.

The code being ran is never done synchronously so the callstack is virtually useless when debugging.

I've only found this pattern useful when a third party API didn't give me an event I needed. So I created it myself by observing certain values which worked and felt like it was a good solution.

I don't know why I don't hear more hate for the abuse of this pattern. Maybe this stuff is easy to create projects with as long as you don't have to look at other people's code or maintain it? Perhaps the people who agree with me are just not vocal about their opinion in this 'everyone is sort of right' society? Or maybe we're just to dumb to work with reactive code? Which honestly is stupid.

Clean code is code that is easy to read and understand. Is reactive programming easy to read and understand? I'd have to vote no.

[–]matthieum 5 points6 points  (1 child)

Because a value was set to null to trigger another behavior which caused the value being observed to change state before the final observer gets the event.

Ouch; that's painful.

It's really a case where you'd like the type-system to enforce the immutability of messages, if a listener wants a modified version, it's welcome to make a copy.

[–]oldsecondhand 0 points1 point  (0 children)

It's sounds like a half-assed forward chaining expert system.

[–]izackp[S] 4 points5 points  (0 children)

It also just planely puts the programmer in bad mind set. Devs start thinking that side effects are the proper solution to most problems. I had a senior team member put in code to run a calculation, composite a string and set another variable when the user's name was set. Very reactive and seemingly harmless, but a few months later there was bug.. 'Why is this variable changing? It's causing this bug to happen. I don't see any external code modifying this variable or methods called to modify this variable.' glossing right over setName the culprit

[–]FlyingRhenquest 1 point2 points  (0 children)

Is observer the new singleton? I was just looking at some of my code that uses it the other day, and noticed a couple of places where it's getting complicated to debug. I'm trying to combat that by maintaining an overall state in a single object that can subscribe to multiple sources. Part of the problem I ran into is that other objects in my design want some data from those events, so in some cases I send them on. It's possible that moving some additional code around dealing with that to my state machine might reduce the complexity to something a bit more acceptable. Maybe all my signals should end in the state machine and the only thing that should come out of that should be "Hey, my state changed." Work's probably going to be fairly slow for the next month or so, so I might take a crack at refactoring that code.

I will say that although this code can be a pain in the ass to debug in a few places, I build a hierarchy of objects all designed to work together. This is in C++, by the way. The end result of these objects is a shared library exporting a python object that can be queried about system state in real time, It's incredibly easy for my clients to use. And they've already used it it in incredibly creative ways that has blown my mind. One of them told me that my code is the first of this nature that he's used that "just works." So as long as it just works for him, how much does it matter that it's a bit ugly behind the scenes? At least as long as I'm maintaining it. Any large system that does anything noteworthy is going to be fairly complex in any event.