JS: Object oriented design
Theory: Builders
Sometimes the creation of an object is a complex process, often with multiple steps and additional conditions. Such objects include validators implemented in the object style.
Validation is the process of checking data for correctness according to a set of specified conditions. And a validator is something that performs this check.
In programming, validation occurs at every step. In one way or another, we work with forms or data sent via API. All this data sent by users or external systems are automatically considered untrusted. Before you work with this data, you first need to make sure that it's “valid”, i.e., it meets our requirements. For example, if we're talking about a user's email, for most registration forms, the field mustn't be empty and must match the format of emails.
The easiest way to do the validation is to perform a manual check:
It's not hard to imagine how this code would grow for a large form with many rules. There are other problems with this method. It doesn't make it easy to reuse rules for different forms and projects. In addition, you will either have to implement the checks yourself, or look for ready-made libraries for them. For example, to check the correctness of links, addresses and other things.
Yup
In JavaScript, the yup library is very popular for performing validation. Look at the example equivalent to the checks above:
The core principle of this library is as follows. A validation scheme is formed using a chain of methods. This chain includes various conditions that must be met according to the principle of union. That is, all conditions must be met for a successful validation. The conditions themselves depend on the type of data being checked, so first you call the method that defines the type, and then you call the methods that refer to that type of data:
In all these situations, our task is to define the appropriate schema for a specific task. This schema can then be used many times on different data. This way of forming a schema object is called a build, and the object itself is called a builder. By and large, this is a slight variation in the use of a fluent interface. How is it convenient? With it, it's easy to build even complex checks using the very clear mechanics of combining calls. The code is simple and straightforward.
Another plus is the availability of ready-made error messages for all built-in checks. If necessary, they can be changed for a specific schema by simply passing the text to the check method:
Yup supports not only different texts, but also different locales, which is important for multilingual sites.
But what do we do in a situation where we're working with an object where each property has its own checks? Yup solves this problem very elegantly using recursive definition:
But that's not all, yup allows you to add additional checks that weren't originally included. You can read more about this feature in the documentation.

