Constant-variable dualism.

Settings for programs have existed for a long time, from the most ancient assembler programs that have constants in their code as settings. Updating such programs occurred with the complete replacement of the code, so changing the settings system did not entail negative consequences. In the worst case, I had to relearn the use of the interface. The situation began to change with the continuity of data types and program settings. At one time, Microsoft paid great attention to the compatibility of programs and data in operating systems, what was their strength. And now support for XP Mode is a continuation of the compatibility policy. In relation to the web, users often have situations where the data and settings they have remain from previous versions (in cookies, in third-party databases), and the version of the program - on the server or the script on the client - changes. There is a problem of compatibility of versions of programs and data and the need to develop some policy to maintain compatibility. The new version may not be compatible with browsers (due to bugs or incomplete support), then a rollback to the former at the time of fixing bugs should not be accompanied by a loss or distortion of the settings, despite the fact that their number may change with the version change.
It requires an approach not just to the settings and their organization, but to the problems of version changes and continuity of settings. Programs on the web are developing in small steps, changing versions often. The same approach to working with settings applies to other programs not related to the web, but with frequent version changes. Similar reasoning can be attributed to the formats of all data in programs, not only to the formats for storing settings.
The main theses that are displayed and worked out in the article:
*) settings - an object for programs and client web applications with similar patterns of behavior;
*) The default settings are nothing more than the manufacturer's recommendations for the settings;
*) changing the settings when changing versions of the program is a change in the manufacturer's recommendations; there may be a version change only for the sake of changing settings;
*) user settings - user recommendations to yourself;
*) export-import settings - the ability to exchange between users, save recommendations, transfer between computers;
(Further - by changing versions.)
*) changing the semantics of the manufacturer settings (when changing versions) - an error that introduces a violation of logic when upgrading - downgrade;
*) when storing 2 states of settings with switching on the “return” button, a number of functions are possible without complicating the interface: try new settings when changing versions, roll back to old settings, try and store third-party recommendations;
*) to preserve simplicity, a more complicated manipulation system is undesirable. There is export-import for all extended actions;
*) Return to the manufacturer settings - a separate function ("Reset");
*) manufacturer's recommendations are “sewn up” into the program, therefore they do not occupy a separate place, there may be several of them (settings profiles), there is a “Save” button for saving other recommendations;
')
Having seen the depth and commonality of the problem of settings and recommendations, let us outline the range of requirements that we will try to support. It is necessary to have a fairly simple and universal system of settings that would work satisfactorily and develop when changing versions. The result is a practical algorithm for supporting the indicated range of requirements. After building the algorithm, we will show the implementation of the settings subsystem to * .user.js and a separate procedure to * .js. It was made out of considerations that it is better to immediately describe the rules for working with settings for yourself and users and not to depart from it than to work out later, correcting your own mistakes.
Circle of requirements: how much the settings will be compatible with the program versions
When changing versions, everything changes - the program, settings, logic and semantics (meaningful settings). Version change is another dimension of the development of logic, which takes into account the arrival of data from old versions, settings from them, and sometimes from the new versions, if there is a downgrade or transfer of settings to another computer, another version of the program. Having modeled the situation of changing versions, we begin to understand which rules need to be followed, and what freedom can be left. Or, in other fashionable words, create a “Settings”
design pattern .
Regarding compatibility issues, each developer vividly recalls the classic nightmare that Adobe arranged with the Photoshop versions in
order to turn out the pockets of customers . Here, most likely, she acted with intent, especially since history repeats itself with their other expensive programs. Worked for 1-2 years with the flagship program of the industry - pay the next installment. Such an approach cannot afford small programs and services, but, on the contrary, version change is required to be done for free and very often, almost with every release of a new version of a browser. A clear and mutually comfortable version change with support for compatibility of settings is required. (And also, one-to-one - data formats and their semantics, but
we will explore only the settings .) However, different users can upgrade far from the previous version, and most users will not bother to work with the settings, or some settings will be missing in general, but be automatic - for example, saving window location parameters in the system.
The system of saving and transition between versions takes into account these facts and provides:
1) storing and restoring settings in the current version of the program;
2) when updating the program - do not forget the old settings in case you return to the old version (at least 1 step back);
3) the constancy of the meaning of the old settings in the environment of an arbitrarily new version (the semantics should not change; why - the analysis below);
4) not to strain the user by tracking the versions and not to force him to take any actions (the best is the enemy of the good; there is no need not to distract);
5) do not strive for gigantism and store differences (diffs) in the settings - an optimization step.
When working with versions of the JS script, which on the client also turns out to be a full-fledged program, the problem of saving the user's settings when changing versions was discovered. Immediately I remembered the compatibility issues of Photoshop versions and some other monsters. And it was thought that to solve the problem of correct work with user settings is better in the embryonic state, until the script went to the masses and many dissatisfied users appeared who would have to manually adjust the new version of the program from memory, or, even worse, the old settings would go into a contradiction with the new version, an untested bug will arise. To offer the user "reset everything and install on a new one" is, of course, a well-known and ugly way of solving such problems with which experienced users have come to terms. (In fact, what can they do with the manufacturer of Photoshop, when there is more benefit than trouble?) It is better to immediately put into the project a technique for resolving configuration conflicts when changing versions. So the rules for working with versions and settings were built, which the program designer could follow.
In the second part in the next article - the implementation of a test page on JS - a ready-made script in which you can test the performance of the approach. In the user settings script, there is an arbitrary multi-level structure, so it can be ported to various projects, which also reflect on the need for a correct version change. Or, using the first and second parts, write logic in another language. Efforts will not be in vain and you can save on the designer's work on the preparation of a beautiful plate of this content:
Before installation, it is recommended to remove the settings of the previous version ...
|
---|
On the policy of saving program settings when moving to new versions.

As already mentioned, changing program versions is entering a new dimension, from solving problems with code bugs in one program sheet to solving problems of its development. Developers may not immediately realize the specifics of this area if they have been working on a number of other very important functions of their program for a long time, and the issue of changing versions is not in the forefront. But once he gets up, and evolution begins.
What happened in the era of dinosaurs: the program when installing a new version starts to work poorly or does not work at all. Recommendation: before installing a new program, delete the previous version (and clear the registry and folder files from the data from the old version of the program). In severe cases - do not open the data created in the old version of the program of the new version.
Another ancient option: when moving to a new version, the program does not ask what the settings were - it sets defaults, and the user installs them manually. Workaround for problems with the program: sometimes they substitute data in ini-files, the registry (win detected), configuration files, and this saves themselves from some of the tuning work. Another solution is to store the program with the image of the virtual OS in which it is installed; put a redisributable package in which they created a working customized image of the program, and then packed it for re-installation; use a silent installation with settings provided for in quite a few serious programs.
The case of more adapted forms of life: the program begins to understand the old settings left over from the previous version. What you need to do when creating a program?
We will talk about programs, now about the web and websites, because there and there is one subject of discussion - the user interface, the versions of the products. Only the input stream is different. For programs, these are settings and their inheritance by different versions, for web, they are data pages and their display by different browsers. Sometimes this data is so similar to the settings that they begin to call it that way, and web pages or widgets are called applications by them.
New settings
The times were good when the new version of the program had completely new settings. Then the question of inheritance simply did not stand. As in the era of dinosaurs, the new version asks to reinstall everything, or use the default settings. But heredity as a basic property of developing systems quickly outlived this shortcoming. Not only data compatibility, but also compatibility with settings has been required from programs. First, the dinosaurs, and then the chickens began to demand eggs, initiating the question of what had appeared earlier. Installed a new version - did not lose the previously specified settings, say, window size and font. But the system of settings from version to version tends to evolve, so one has to take into account the program development, the evolution of life forms. And yet, the program can be updated to any version, even to an older one, which means that it should correctly use not only any previous settings, but also settings in any future format!
For example, in the system of tags and attributes of HTML, XML there is a rule: if a new attribute or tag is encountered, it is ignored (its meaning is unknown). Obviously, it is logical in the system of settings
when new ones appear - to ignore them . So, in the HTML pages, and even earlier - in the program settings for different versions of the same program, they introduced the very first and simple compatibility rule.
Interpretation of available settings
However, even with the same settings, the program may (by mistake) begin to interpret some setting differently. If the programs are from different manufacturers who receive the same data from the user, they can interpret the data in several different senses. For example, for some, the screen size takes into account the first monitor, while others have the maximum measurement from the group of all connected monitors. If we again turn to the analogy with HTML, then this is known in HTML as the problem of compatibility of data representations in browsers. Even identical data (tables, input fields) cause a slightly different display of results.
There is a problem - they took up her decision. Now there is a “compatible” view, but there is a strict one. With a large number of browser versions, the number of strict views grows, and compatible ones grow even faster (squared), because Each browser and version will have its own idea of ​​compatibility.
If we took this approach for compatibility of settings in programs, then we would need to write rules for transferring settings between versions. Because the installation of versions does not always occur sequentially. There are jumps over versions, there are returns to the previous ones (for example, due to the bugs of new versions). It is clear that this process, even if it is started at the level of 2-3 versions of the program, will quickly get bored by the developers, and they will start to support only the most current compatibility - the transition from the old version to the new one.
Adhering to a single line of conduct is the best means of building the Tower of Babel.
The disappearance of the old settings or some of their values
If in the new version of the program (or even with a new launch), the values ​​set in the settings were no longer supported, the program should respond adequately to this.
For example, in the same era of dinosaurs, all (or many) programs believed that they should appear in the middle of the screen and occupy about 50% of the screen width. If the user decides to change the position and size of the window, it was not at all necessary that the next time the program opens the window in a new location. Why is that?

If the program remembers the position and size of the window, then another time it may easily be out of the screen if you change the monitor. Support for the program is complicated, and evolution has not always supported complex life forms. Seeing the monitor and the environment is a long procedure that, in an undeveloped API, created hell for the developer, and they (or these ideas from them) died out, even without giving offspring - the programs working in this key. Programs could be extremely difficult, but have a primitive interface, because each additional action on a working program could give a series of bugs and the need for a new testing cycle.
But years went by, and with the advent of more advanced APIs and development environments, the developers gained strength and confidence in the future.
The dinosaurs were overgrown with feathers and began to fly. Now it’s quite realistic to see that if the program took an unacceptable value from the settings, it will not be bent in agony and will not be swept away by the ruthless hand
of the user's
nature , but will act rationally.
Reasonable alternatives:
1) select the nearest similar value;
2) select the default value;
3) to offer a choice of a complex of related values, since changing a parameter sometimes requires changing others.
A reasonable program reacts to an invalid value for this version .
Change the semantics of customization
This is the most difficult case of the program tangling its previous settings. If the control of settings is based on the transfer of the name + value of each setting, then the distortion of the meaning (that is, the actions of the program) of the value will lead to an uncontrollable change in the behavior of the program.
For example, earlier 1 is to open in full screen, now in a large window.
The understanding of the default setting has changed, and default values ​​are not stored in the settings file. Obviously, the presence of such changes in meaning will lead to errors and will require correction.
Thus, as browsers tend to call white white (though not always, for example, the page's background is customized), so the program tends to see in the settings what they have in mind. (If some windowWidth variable indicated the width of the window, there is no point in the new version of it indicating the number of employees in the enterprise.)
Not everyone is doing so frankly. Here is an (hypothetical) example of a very secretive change in meaning. To version N, the width of the window in the OS was considered by the developers along the inner border of the window, and from the Nth it was decided that it would be more correct to count along with the border. And then, if the user previously set the width to 100 in previous versions, in the Nth he will receive an internal width (still meaning) of 98, 96, or another, depending on the OS settings. In the place of the developers, if you need to enter a different width, you need to choose a different name (name, key in the settings). And the former, as unnecessary, can be permanently deleted (or leave the conversion procedure, only for version compatibility).
Changing the semantics of setting values ​​should be considered as a developer error.
Change of default value
The most innocent case of the resulting disruption.
For example, there are 2 checkboxes, both selected. The first checkbox was cleared by the user, the second was arranged by him (and if he had not been selected, the user would have chosen it, because he wants values, 0, 1). In the next version, the manufacturer dropped both checkboxes. The user in the saved settings has only the choice of the first: 0, X, where X means giving the choice to the manufacturer. And it has a problem, because the interface did not have and there is no possibility to fix the default value of the second checkbox.
The result is a different system of settings for different users. Everything is in order with the passive and problems for active, not able to fix the choice of default settings. (This is followed by the recommendations of professionals in related fields - CSS, for example - take into account the actions of attributes by default, writing them explicitly (CSS reset), so that if the default policy is changed, no other understanding of attributes arises in the future.)
The way out is to give the ability to fix the setting, even if it is in the default value. In other words, the user will express a clear desire to set this value, and not passive consent to the manufacturer’s settings (recommendation). Consequently, we can not, as is usually done, not give the opportunity to specify the fixation of user settings in the same value in which it is now.
(This was the thinnest moment, the system crash without fixing the default settings, which made the problems to be disassembled.)
In voting systems, if someone has already voted the same way as the user, it does not mean at all that the user cannot vote as well. Similarly - in the settings.
“Facilitating” the choice of the default setting without the possibility of confirmation, fixing it in the interface is a “disservice” and a source of problems. With fixation - the balance of the manufacturer's recommendation and the user's choice is observed.
In our case with checkboxes, you need not only to give changes to the settings, but also to indicate the fixation of each. For the optimality of the process, if the user has changed something, this already means fixation. But now it must be able to remove it - to return to the default value, again, for each setting. Similarly, to return to the choice of another authoritative user, if the system supports more than one settings profile, but imports other authoring settings as well.
Further, the manufacturer makes the change of settings for a reason, so it is useful to know about it, in an unobtrusive mode. If the user is interested in the settings, he should see what is new with what happened to them since his last entry into the settings. If he came in for the first time, nothing stands out, everything is new. If something has changed or fixed before, and the manufacturer has changed his recommendation, the user will see the change.
The developer provides an indication of the change of default settings .
The question smoothly approaches the system of help, tips, information and selection of recommendations. A place to notify you of changes to settings is also the best place to describe the settings in general or to give hints on them.
Consequently, the interface for selecting a setting is cluttered with 2 elements: fixation / unlocking of the fixation and a hint both on the change history and the description of the setting in general.
Like this (the controls are just listed):
[0] - _1 (?) _fix_ [1] - _2 (?) _unfix_ [__] - _3 (?) _fix_
In square brackets - the value of the checkbox; question marks - tips; The color of the questions may indicate that the system has something to say about the changes. “Fix / unfix” badges - links to fixing defaults or return to them. If there are several recommenders, fixation icons become more complicated. You can have in a series of settings - an indication of the users who chose this setting (how many and with what status), and among them - the value of the developer settings. With this approach, settings begin to resemble social network ratings. Well, maybe this is one of the options for collective use of programs.
If there is no fixing mechanism, we have interface and logic problems. However, in the checkbox interfaces in the OS, this problem was solved by going through 3 states: 0, 1, default. In HTML, it can also be solved by using disabled and looping through JS. Then, at least, the check / radio buttons will not require the fix / unfix element.
What if the work of the new version did not suit?

In this case, obviously, a rollback to the latest version is required. However, some data may remain new (usually from the subject area), and program settings should be taken from the old settings, but some of the new settings may also be useful and saved as a recommendation for old or for a new stable version.
... The second time the word "recommendation" appeared. This is unusual for settings. There is a “default value” as a developer’s recommendation, there is (sometimes) a reset to the default values, but there are no recommendations. There is an import of settings, but then all settings will take on new values, and can only be compared with what was before the shift. A recommendation is an opportunity to try to change the setting or their group and immediately see and compare the result.
The idea of ​​recommending and comparing is very powerful. (By the way, evolution worked in the era of dinosaurs as well.) A number of store sites try to provide the most convenient products for comparison. This is the same selection recommendation as a recommendation to set some customization. Therefore, if we are able to show in the program the implications of the recommendation of the setting, the prospects will open to do a lot more and unexpectedly useful with the same tool.
Let's go back to the rollback version. To make a full rollback, the program should not unconditionally forget the old settings. It is better
if she remembers the last step of the program version change . If the user did not have time to try out all the capabilities of the previous versions - let him remember the previous steps. Then he will be able to identify the latest correctly working version. Obviously, this will be useful for development and testing. In the era of the dinosaurs, this has not happened ...
Reasonable Interface Restriction
True, I would not want to complicate the choice of settings so that to operate with several sets at once. This is good for professional testers and other developers, but there is a task to make a mass control, therefore it is better if it is as simple and flexible as possible. Usually,
flexibility is achieved by exporting and importing settings . With it, a user in a separate place outside the program can implement any system for cataloging and storing versions, which again, is difficult. In addition to an omnipotent export system, it would be good to have a simple subsystem that does not require exporting as much as possible.
Let's try
to keep not 1 list of settings, but 1 or 2 , relating, for example, to the current version and to the previous one. Or the current version and experimental. Then in the management interface we need to have only one button (like in calculators, the “M” (memory) button) to switch between our settings and not be confused in them, not to enter names and not to build a “manager”. For all that is more, export is available. This fundamental simplification of the interface will hopefully allow us to build a practical model and remain as intuitive as the “M” button.
The starting point of such an idea is that most of the actions, including checking the new version and rolling back to the old one, do not require operating with more than 2 lists of settings. Checking someone's recommendations with the storage of one "set" of their settings - too. Next, we describe the technical implementation.
Storing settings means placing them in localStorage to use within the browser, regardless of reloads. In addition to the stored sets, you can temporarily test other settings without affecting the stored ones. Saving is done by clicking the "Save" button or downloading a new version of the program. You can roll back without using new settings (default) or using (specified when rolling back). Switch to an arbitrary other version - with a choice of the same two. New settings are selected if the version number is more than the version version of the new set. If 2 sets are the same, it is still considered that there are two. They are stored as differences, therefore, the smaller the differences, the less space is occupied. The current settings are stored as the difference between the manufacturer's recommendations and the user choice. The difference is understood as an indication of the setting if it is selected by the user (even if it is the same as the default) and if not specified otherwise.
There is one more technical point that in the browser it is most simple to implement the reading of the settings at the beginning of the page loading, and then consider them constants. The process of changing the settings requires a reboot, so some testing requires saving a set of settings, and in order to forget the user's settings, you need to store 2 sets and then use the same “Return” button to restore.
What can we do with 2 lists of settings? We will collect a complete list.
1. Go
to the new version of the program and download the new settings from it. Old ones will remain for rollback, and new ones - for continuation of work.
2. If rollback is performed, the
data of the new settings are saved in the second set, if the user has changed them. When re-moving to the same or a newer version, the accumulated one is used.
3.
Saving another recommendation (import - save) erases the data for rollback, so that the settings of another recommendation can be explored after restarting the browser.
4.
Testing other settings (settings - test - save), which can be continued after restarting the browser and after reloading the page.
Nothing prevents testing the settings without saving them, but then we are limited by the time limits until the page reloads. So you can test the most simple and immediately effective settings. Most of the settings set their values ​​in the program just at the beginning of the page loading, so they cannot be tested without saving to localStorage. The mechanism of saving 2 sets of settings allows testing without such restrictions, which creates a good addition to the capabilities of scripts.
Why so much attention to the amount of data and their limitations?
Because, on the one hand, there is a desire for simplicity and clarity of settings. The smaller the entity, the better. The simplest thing is to have one set of settings - “my”. For a minimum of manipulation, the settings “other” are entered and the only button to switch “Return”. Confusing is difficult, but adds features. There is another side to the question.
It would seem that the difficult thing is to transfer the settings to the server in the database, and there it is no matter how difficult to work with them: store for each version, review the history? Here we come to a couple of other entities of our task. The first is to store the settings regardless of authorization on the server. Without authorization or for another task - as user preferences on the client, where authorization is also not intended. The second essence of the statement is that storing the settings in text form for export implies the most compact form of storage, so you need to have the shortest and manually editable string. Therefore, there are 2 sets, and only the differences of settings are stored so that there is less data.
Interface switching settings

This section requires a separate article and another blog. What we did before is called “Program Architecture”, but there is no such blog, there is only the “Architecture” tag. To make the description complete, let us describe the results briefly, in words, without illustrations, and we will take the details to another article It turned out, as usual in text descriptions of interfaces - boring, hard to read
and intended only for those who are engaged in similar and want to compare the results.
At the beginning, without any special actions, the user does not receive any additional elements in the interface anywhere, until he starts to try to change the settings. There is even no (or not activated) “Export” button, because exporting an empty line is, by default, accepting the manufacturer’s settings.
There is a button (or input field) "
Import ", which through the input field we load a string JSON or something similar to change the settings. Immediately we see the reflection of these settings in the settings interface, the name of the recommender, the version of the settings + the version of the program for which they were made. There is nothing unusual if we load the settings of an arbitrary version into another version of the program (old or new). Those whose keys can be found in the current version of the program will work. The test buttons "
Test " and "
Cancel " appear. The second restores the viewing of its settings and does nothing, and the first saves the uploaded imported version as up-to-date, and the backup as current, erasing any other backup version if it was (single-level stack).
The presence of the saved backup version is marked in the settings panel. Therefore, as soon as we press "Test", the information on the saved version of the user will appear on the "
Return " button, which will come in (it may not be if the user settings were not, but the "test" mode still turns on). A constantly hanging link to the “
test ” settings box appears in the page interface (as a reminder of incoming mail).
When you click on “Return”, you get the settings returned for the program (usually activated after the page is reloaded), and in the settings panel - the settings for the test and the “Test” - “Cancel” button are the previous operation step.
If a
new version of a script (program) is being
loaded , as noted by localStorage analysis, it acts on the state of the settings in the same way if they were changed. A copy of the old settings is created and ... similarly to the “test”, the “
new version ” notifier appears. If you do not do this, changing the program’s behavior will be puzzling to the user. This raises the question whether to show this button to everyone or only to those who are interested. Most likely, the second, and for all - the notifier hides in the settings panel.
If the version is changed repeatedly, nothing really changes, only the value of the new version of the script (and the new settings). If the user has changed the settings for the new version, the "
Save " button appears, on clicking on which
2 groups of settings appear : to the new version and to the old one. “Return” will cause a version rotation: the word “Return” will change to “
Apply new ” to switch to the new settings again, as in the “Test” case. To return to the old program, you need to press the appeared button "
Rollback ", which will occur on the version whose number is remembered at the last edit of the old settings. (This mechanism requires access to any released version.) To switch to other versions, a drop-down list of numbers.
If the user has changed the set of settings again, when 2 sets have been saved, but the 3rd version of the program is available, there will be no new saving in the stack, only the current group will change (after clicking “Save”).
The "
Confirm settings " button - to refuse to store the memorized state - rollback, remaining on the new version (the "new version" icon is deleted). If the state is one, the button is called “Erase settings” or “
Reset ”, and the memory is cleared of the settings, the default settings are used. "Reset" is protected from accidental pressing.
Given the
restriction of the number of sets of settings to two , any test action will erase the rollback settings and will not restore them at the end of the test. In order not to lose them, use the
export button, which is activated when there is any custom setting.
Let us list again the list of buttons and notifiers and their grouping:
* Import, Export - for making-retrieving settings as a string;
* Test, Cancel - apply settings, cancel import display in settings;
* "Test" - the notifier, prompting that the settings are in test mode;
* Return - restore your settings, exit the test;
* “New version” - a notifier that speaks about downloading a new version (in the settings panel);
* Rollback - the analogue of “Return” to roll back to the previous version;
* combo or list of versions - which version will be rolled back;
* Save, Cancel - confirm the change of settings from the user; similar to “Test”, but without notification;
* Confirm settings (instead of “Return”) or Reset - deleting stored settings, applying current (or default) settings, removing the “new version” notifier;
* Apply new - after a rollback - go back to the new version of the settings.
In the next series we will try to see all this live, but it is quite possible that this will not work in the script yet, and nobody will need to write an article with a drawing of the interface - programming goes without layouts. Then wait for the public script with the described mechanisms as a demonstration.
Results
An interface for working with settings without technological flaws was obtained, which could be without taking into account the development of the program when changing versions. The concept of “recommendation” has been introduced, and it is possible to work with several recommendations and with a settings format compatible with the version of the program in any direction - working with both new versions (for upgrades) and old ones (for kickbacks).