DEV Community

Discussion on: JavaScript vs JavaScript. Fight!

 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

Isn't that exactly what I'm proposing though? Having the data live in one place, and an mutation observer sitting on top of it changing the UI to reflect data changes. The data doesn't need to know about the UI and can live in its own little (testable) world.

User actions could then be passed back to the data as events, and suddenly the whole thing starts looking a lot like an MVC design. Or, if we want to look at it from the object side, we'd end up with two objects that communicate through message-passing, which is also an excellent way of de-coupling different parts of an application.

Thread Thread
 
peerreynders profile image
peerreynders

Having the data live in one place, and an mutation observer sitting on top of it changing the UI to reflect data changes.

My interpretation of your statement is that you are proposing a variant of MVC where the mutation observer is intimately familiar with both the model and the view - i.e. is tightly coupled to both. The logic around such a mutation observer would be anything but so simple that it can't possibly break.

The data doesn't need to know about the UI and can live in its own little (testable) world.

The point is to create the conditions where you don't need to microtest the dumb UI at all - delaying that part for integration testing.

and suddenly the whole thing starts looking a lot like an MVC design.

Even Pattern-Oriented Software Architecture Vol.1 (1996) lists some hefty liabilities for MVC (p.142), in particular:

Intimate connection between view and controller. Controller and view are separate but closely-related components, which hinders their individual reuse. It is unlikely that a view would be used without its controller, or vice-versa, with the exception of read-only views that share a controller that ignores all input.

A consequence of the tight view/controller coupling is that with the controller being the most complex piece of the pattern a "dumb view/controller" becomes essentially impossible.

Close coupling of views and controllers to a model. … You can address this problem by applying the Command Processor pattern … some other means of indirection.

(p.136)

apply the Command Processor design pattern. The model takes the role of the supplier of the Command Processor pattern, the command classes and the command processor component are additional components between controller and model. The MVC controller has the role of controller in Command Processor.

This is already is starting to look more like something like Flux where the "commands" become events or actions. The problem with the controller is that it orchestrates - orchestration logic tends to be complex. Sometimes choreography lets you break up that complexity into smaller more manageable pieces - ultimately that's what a state that accepts actions and supports change subscriptions is all about. That way an application can be built in terms of application actions and subscriptions to application events.

However in some cases the flux-style single global store just isn't optimal.

Aside: MVC: misunderstood for 37 years

So the ideal scenario is where "dumb UI fragments" can be updated via application event subscription (thin events requiring additional querying of the application to obtain relevant view state or fat events containing the relevant view state) and affect the application via application actions. The application gets to dictate the shape of the application events and application actions. The dumb UI depends on the application - not the other way around nor is there something (complex) sitting in the middle, brokering everything.

Thread Thread
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

That MVC thing was a bit of an accidental red herring. Personally, I don't really like the idea of using MVC as a design philosophy on its own and only wanted to mention the similarity. More than the MVC part, I'd focus on the message-passing aspect of it, which to my knowledge is about the most decoupled way we know for two parts of a software system to interact.

Let's skip the controller part entirely for now, and just consider the data (model) and the UI (view): Ideally both would send very generic messages to the other, so neither would have to make any assumptions about the other.
But even in a more "real world" example, it will more often be the UI that will depend on certain assumptions about the data, not the other way around, which I find ideal.

This way, if we put the business logic on the data side (aka. coupling model and controller), we can reason about that side and test it independently of the UI.

The similarities to MVC are obviously still there, but more in the sense that it's a way to categorise components of our application, not a template for how to build it in the first place.

If any single paradigm could be used to describe this form of application structure, it'd be the original idea of Object Orientation (one that's more about message-passing and less about classes and inheritance).

Thread Thread
 
peerreynders profile image
peerreynders

(one that's more about message-passing and less about classes and inheritance).

That's not the mainstream perspective but the Joe Armstrong perspective:

… but Erlang might be the only object oriented language because the 3 tenets of object oriented programming are that it's based on message passing, that you have isolation between objects and have polymorphism.

And loitering here a bit subscribe-notify is a common communication pattern between BEAM processes as it decouples the Provider from the Subscriber. That is the relationship that you want between the application (Provider) and the dumb UI (Subscriber) in the context of UI updates. The beauty of that approach is that update logic doesn't have to know which parts of the UI are active to push updates out but only has to supply updates to the parts of the UI that are currently subscribed.

Aside: You may find David Khourshid's XActor interesting (and visit his Redux is half of a pattern articles while you're at it).

Ideally both would send very generic messages to the other, so neither would have to make any assumptions about the other.

Not sure about the "generic message" and "no assumptions" aspects:

  • "the application" needs some very specific information from the messages that it receives in order to act on them.
  • "the application" will likely publish messages of a very specific nature as unnecessary flexibility/configurability will lead to non-essential complexity.

"The application" leads, the "dumb UI" has to follow.

That said there is also a Consumer Driven contract dynamic between the consumer "dumb UI" and the provider "application". The UI has to fulfil its intended purpose so the application has to make accommodations:

  • The "dumb UI" depends on the application's contract
  • But the application contract is aligned with the needs of the consuming "dumb UI"

The aim isn't "loose coupling" but an application core that has no direct dependencies on the UI.

Nicolai M. Josuttis: p.9 SOA in Practice

Loose coupling is the concept of reducing system dependencies. Because business processes are distributed over multiple backends, it is important to minimize the effects of modifications and failures. Otherwise, modifications become too risky, and system failures might break the overall system landscape. Note, however, that there is a price for loose coupling: complexity. Loosely coupled distributed systems are harder to develop, maintain, and debug."

i.e. we're investing in just enough complexity to keep the application decoupled from the UI - but no more.

but more in the sense that it's a way to categorise components of our application,

There is that word again - component.

A physical, replaceable part of a system that packages implementation and conforms to and provides the realization of a set of interfaces. A component represents a physical piece of implementation of a system, including software code (source, binary or executable) or equivalents such as scripts or command files.

At least that's what the UML modeling glossary states.

don't assume the word component means the same thing to everyone.

😁