Event or no Event?: My Take on this Blog on Think-Cell Developer Blogs

I was reading the Think-Cell blogs, and I found this rather very interesting post on their blog about Event or not Event?. The goal of this post is not to say anything is wrong, but, more like to critique the way that this blog was written and how, to me, as a reader, this leaves more questions than it answers. If that was the initial intention with the trailing “?” in the title, then great piece of article. If not, then, well, perhaps continue reading.

Oh, and by the way, if you’re the original author of the blog, I’m happy to address any feedback on things that I might have missed.


The precontext is great, and it greatly expresses the nuances of UI applications. Many frameworks, Qt for C++, or Windows Forms and WPF for .NET, for example, do offer the same behavior. The observable patterns for the UI development enable the developers to author the code where the app self-builds itself. The newer way of doing this is via declarative UIs. Before that, let’s review how a UI application can keep its controls up to date with the live (or near-real-time data):

  • #1: The code-behind polls the data, and updates the UI controls and their value. No event handling required. That is how I did the UI back when I was a junior engineer back in 2011 and 2012, and I did not want to enter the complexities of events and delegates.
  • #2: The application uses an architectural or code-level practice of communicating the changes outside the scope or context. This requires a callback, an event, or a delegate. These pointers raise events and send notifications to the subscribers to update themselves.
  • #3: The UI and the logic and content is separated behind a layer of “state”. The UI is updated only when the state changes. In these scenarios, the UI is refreshed (rebuilt) when the state changes.

The third practice is used by declarative UIs, such as React, Flutter, etc., and is high-performing for non-frequent updates and rather simpler UIs. Once your UI becomes complex, with multiple updates, and multiple update points (fields, properties, objects, etc.) then the declarative UIs and the frameworks become a bottle neck.


Now, the blog. To me, there are two main technical faults in the blog.

First, the blog mentions that this was discussed during a “code review”. But it removes or ignores the context, as to what kind of code review it was, or the pseudo-code that was under review. I am not saying the exact code should be shared, but the nuance of the change must have been communciated to give the reader a context. Without the context, it is difficult to observe why the OnTextChange should be avoided.

Then, the question:

    If SetText modifies the text, should the OnTextChange event fire?

    Event or no Event?

    I think, it must always fire the event to notify the observers or subscribers if the architecture of the application is designed in such a way.

    If the application and library is not designed to communicate to the clients, then sure. To keep the contract, if the platform has events, then fire them. Hyrum’s law dictates this.

    And the second point,

    Changing what the callback does is much harder: the code needs to transport the context into the callback.

    Event or not Event?

    This depends on whether you are building the software that needs to be extensible or building the hardwired library that only needs to update and modify the behavior of the software on specific and limited scenarios.

    If you are building the software as a library for others (developers or non-developers), it is good to offer the choice of behavior to the end users. If I am consuming your library, I would appreciate if there is an event that I can subscribe to, and process the updates myself. If I do not want to process the data, such as to avoid the validation on the user’s input as it enters, I can completely ignore subscribing to it at all.

    If the “event” is truly an event, it does not need to communicate anything. C++ is powerful enough to check whether the callee or caller exists in the source code and strip the code as needed; but that is a different conversation.

    This statement,

    To make matters worse, the behavior dealing with the SetText scenario is now implemented in the callback

    Why?

    SetText should follow the single responsibility principle and just update the text value wherever it is. For SetText, it should not care whether it has subscribers to notify or something else to do.


    The agreement

    That said, the statement about, “So in our UI library, we follow the rule that only user interactions trigger events.” is a completely valid argument and a choice.

    I guess, we agree on this. I would send a copy of this blog to Think-Cell as well, and I mean to share this in a feedback-capacity not to point fingers, and I would love to hear their thoughts and feedback. 🙂

    Thanks!