📜 ⬆️ ⬇️

StateController. Event model in the development of interfaces. Part 1


Introduction


Now more and more JavaScript frameworks appear, which are somewhat different from the current fashion jQuery. Some try to implement MVC, others provide a tightly coupled architecture, others aim at asynchronous, and so on. Each developer chooses what is closest to him, and that most effectively solves the task. Therefore, I will not discuss the advantages or disadvantages of frameworks, but I will tell you what we have come to in our products, what concepts were developed and what problems were solved.

I will begin, perhaps, with the task. We built SaaS, an information and analytical system that operated with substantial amounts of data. The user could receive quite a large amount of information in one request, but at the same time could clarify some blocks of information, moving to an even greater level of detail. If we had built the classical scheme of a multi-page application, we would get a sad data retrieval rate from the database, a large amount of transmitted traffic, but most importantly, the market would not satisfy the demand, which would require as little waiting time as possible to respond to requests. Therefore, we chose a model for building a one-page application, when data is loaded on demand and only those pieces that the user needs at a given time. They killed three birds with one stone at a time.

Single-page issues


Such an application requires a special approach to code organization. Some standard solutions familiar to the world of multi-page applications, with a single-page approach, climbs sideways. Imagine that a user, using the program for its intended purpose, after a time has loaded a total of 10,000 tags into a document. The jQuery approach (choose the right one from the whole document) can cause a serious degradation of the speed of work. Of course, you can reduce the visibility of the selector, but this is not always possible, and requires additional painstaking optimizations.

Another approach that required revision is the model for building the module itself. I tried to get away from MVC as applied to HTML, because it required a substantial amount of work with very questionable efficiency. Modules should be loosely coupled, have no means of direct communication with each other. Where to store data? Why not use HTML for this structure! DOM provides smart and convenient tools for working with data structures, actually being a ready-made Model.
')
It remained to find the "threads" that all this had to be stitched together. The only option that occurred to me was to use an event model. This is how StateController v2 appeared.

How does the event model work?


It is built on two main components: handlers and event generators. The events themselves may be impersonal and named. An example of an impersonal event is a function or method call.
foo(1)

You call this function because you need to perform some action or get a result. Although we can formally call the event as “perform an action” or “get the result”, it does not appear anywhere in the explicit form. The handler is the function or method that is called.

An example of a named event is click . Everything is clear, familiar, familiar. The generator triggers a specific event, to which some handlers respond.

Structure-event model of the application


The desire to get away from the classic MVC in JS, together with the requirement of weak intermodular communication, led me to the following conclusions:

The best data storage - DOM structure
In order not to make unnecessary data synchronization between JS and HTML, we carry out modifications directly with the DOM structure. If you still need data in the form of JS-objects, collect them at the time of calling the methods in temporary structures, then throw them out. At first, this seems somewhat illogical, because you have to collect information on every sneeze, but maintaining the consistency of shared data will be more expensive. Especially in single-page applications, where there is no guarantee that at this point in time, some DOM branch will not appear in this place, which one of the modules loaded at the request of the user.

Better communication between modules - events
Teaching modules to generate certain events is much easier than linking their handlers to each other, so that when modifying data with one module, the machine can perform all the necessary actions in the related modules. A kind of polymorphism, a single communication API.

Nodes as handler carriers
Shifting the “responsibility” for the actions performed to the final nodes of the DOM tree, we obtain another abstraction - scripts. Better than a particular node, no one knows what to do in certain cases. Thus, the structure of the DOM document carries the logic of operation. Here lies the most basic difference between the approaches of event and selective framework models.

The logic of developers who work with a selective approach is something like this: choose the right nodes and perform a specific set of actions with them. The logic of the event approach: someone must perform a certain set of actions, because the system has changed the state.

It seems, and not much different, you say. Let's solve the following problem. We have three elements of the form: the registration address (ra) , the residential address (la) , the checkbox "The residential address matches the registration address" (ch) . By default, the checkbox is in the marked state, the residential address is hidden. If the user removes the tick, we show him the field with the address of residence. When the checkbox is turned off, the input form is not only hidden, but also cleared of user input. Nothing complicated.

An abstract implementation using a selective technique would look something like this:
  1. Hang up the click handler on ch , which will do 2
  2. If the state is checked, then 3, otherwise 5
  3. Show la
  4. Output
  5. Hide la
  6. Clear la
  7. Output

An abstract implementation using the event method will look like this:
  1. Hang up the click event handler on ch , which will do 2
  2. If the state is checked , then 3, otherwise 5
  3. Launch event equal_data
  4. Output
  5. Start event not_equal_data
  6. Output


  1. Hang handler equal_data on la , which will do 2
  2. Hide node
  3. Clear form
  4. Output


  1. Hang up the not_equal_data handler on la , which will do 2
  2. Show node
  3. Output

At first glance, the second implementation seems somewhat more complicated. But let's look at the "stability" of the code to modifications. What happens to the first block of code for each of the approaches if we need to add some additional action, for example, to show some contextual help, the text of which is different when the checkbox is active and inactive. We will have to go to the handler and add the necessary actions for the selective model and do nothing at the event. Even if there are one hundred edits, the first block of the implementation of the event approach will not change, because it is abstract and contains an execution script, but not concrete actions. In practice, this is expressed in several buns.

Positive moments from the event approach


The time for testing decreases, because when editing, the basic logic of the work does not break, only handlers are added, and vice versa, handlers are not dependent on script changes.

The principle of KISS in action. The script is easier to read than the final implementation code. If the handlers are made “stupid” to perform some specific actions, then it is much more difficult to make an error in them. Yes, and the portability of the code turns out to be quite impressive, the libraries of the handlers migrate between projects, sometimes with scripts.

Negative moments


Threshold of entry. Reading specific directives is much easier than tracking the entire path of an event and the consequences of running a script. For an untrained developer, the code of the event model is more like magic, something is taken from nowhere and disappears somewhere.

There are tasks that are easily solved by a selective method, but not a fact that will similarly come out with an event-based approach.

In the next article I will move closer to practical implementation.
Part 2

Thanks for attention!

Source: https://habr.com/ru/post/173023/


All Articles