3 ms·
tl;dr I think he's using a message bus in a mobile app the way you'd use Redux in a web app. First off I have to quibble with his terminology. Usually people
by dkarl 9y ago
tl;dr I think he's using a message bus in a mobile app the way you'd use Redux in a web app.
First off I have to quibble with his terminology. Usually people say "message" when the sender specifies who will receive the message — perhaps only by a name that is resolved later, but at least that much. What he's talking about sounds more like "events" that are broadcast for anyone to read or ignore as they please.
Anyway, he isn't entirely specific about how he's using these messages, but if he's using a message bus global to the app in order to communicate between different parts of the app, I found it to be tractable and very convenient when writing an Android app. Before I started using the message bus, wiring up connections between different parts of the app was a real pain, and it often had to be redone as functionality changed. When I started routing everything through the message bus, it was marvelously simpler. I just connected everything to the message bus. Obviously that's a recipe for disaster in a large enough system, but I would guess it's a rare app that gets large enough for this to become intractable.
With MOP, A dumps its output on a bus, and it's picked up by B, which dumps its output on a bus, and it's picked up by C. Now, in order to understand the composition, you need to trace the thread through the entire system, probably using string search - and not be certain you've got it right, because of modalities that may not be explicit.
You're right that this is a difficult way to think about it, but there's a much simpler way. You think about elements in isolation and their responsibilities. You have a component that communicates with the back end; one of its responsibilities is to signal when the auth credentials are missing or invalid. You have a component that controls navigation; one of its responsibilities is to pop over a login window and push it onto the navigation stack when the user is prompted to log in. You have a behavioral component whose job is to detect the lack of credentials and signal that the user should be prompted to log in. Each of those components can be tested in isolation, and the only thing that unites them is a list of the messages and their meanings. If the responsibilities of each component are defined in reference to the same set of messages/events then it's clear that if one thing doesn't lead to another then some component isn't fulfilling its responsibilities or the responsibilities haven't been designed correctly.
Again, just as with Redux, I can see managing these interrelationships becoming intractable in a large enough system, but I think it works well for a moderately complex app, and simplifying the plumbing is a huge win.
EDIT: In response to you need to trace the thread through the entire system, probably using string search, if you're working in a statically typed language, you don't need to rely on string search; you can just search for usages of the type of each message. For 90% of the event types you'll find two usages: the place where an event is fired and the place where it's detected and responded to. Most of the rest will be fired or read in multiple places but still a very small number.
- WorldMaker 9y ago> In response to you need to trace the thread through the entire system, probably using string search, if you're working in a statically typed language, you don't need to rely on string search; you can just search for usages of the type of each message. For 90% of the event types you'll find two usages: the place where an event is fired and the place where it's detected and responded to. Most of the rest will be fired or read in multiple places but still a very small number. I think this gets to the crux of the nature of the solution. You are trading one very strongly statically typed message-sending apparatus (function calls; object member calls) for one more weakly statically typed message-sending apparatus ("events"/"messages" as standalone objects). While, yes, you can get static typing hints back, for instance, by using statically typed Symbols/Enums for "message types" as opposed to using more stringly typed options, you are still trading very strict static typing (I'm calling this specific function, I'm acting on this specific object) for weaker static typing. There's nothing wrong with using weaker static typing, of course, and it's nice having a spectrum of options. (It's also why I think it's silly to think its an either/or between OOP and MOP; they are a paradigm spectrum that isn't entirely mutually exclusive and often you want some of both worlds.) It's a trade off, and should be a clear trade off, and knowing that is half the battle.