JavaScript pattern CustomSwitch / Hebrew

JavaScript pattern CustomSwitch / Hebrew

Introduction

This article will look at the CustomSwitch pattern, which can be used in a variety of situations and programming languages. In this case, we implement CustomSwitch in the JavaScript programming language. However, it is worth remembering that this is far from the only possible language for its implementation.

Using

The first two screenshots show the game engine code. For the second example, I’ll provide the author’s code and my code that uses the CustomSwitch pattern.

Author code:

nextPosition(initialX, initialY, direction) {
    let x = initialX;
    let y = initialY;
    let size = gameConfig.TILE_SIZE;

    if (direction == 'right') {
        x += size;
    } else if (direction == 'left') {
        x += -size;
    } else if (direction == 'up') {
        y += -size;
    } else if (direction == 'down') {
        y += size;
    }

    return { x, y };
}

My code:

// значения координат игрока/игрового обьекта и его направление.
nextPosition(initialX, initialY, direction) {
    // Что нам нужно изменить
    let change = {
        x: new Number(initialX).valueOf(),
        y: new Number(initialY).valueOf(),
        size: gameConfig.TILE_SIZE
    }

    // направления игрока, массив где первый элемент какую координату изменить в change обьекте, второй эелемент это размер тайла в положительно либо отрицательном значении
    let match = {
        left : ['x', -change.size],
        right: ['x', change.size],
        up   : ['y', -change.size],
        down : ['y', change.size]
    }

    // обращаемся к обьекту где мы изменяем значение что нам дает в массиве первого эелмента и прибавляем значение размера тайла в положительном либо отрицательном значении.
    change[match?.[direction][0]] += match?.[direction][1];
    return { x: change.x, y: change.y };
}

In both examples, the function nextPosition takes initial coordinates (initialX and initialY) and direction, and returns new coordinates.

The first code without the CustomSwitch pattern uses conditional statements if and else if to determine the value of x and y coordinates depending on the direction. Here, each condition checks if the value of direction is equal to a certain direction and, if it matches, changes the corresponding coordinate.

The second code with the CustomSwitch pattern uses a change object that contains the initial x, y and size values. Then the match object is created, which is an associative array, where the keys are the directions, and the values ​​are the arrays containing the variable coordinate and the amount of change.

Next, using the abbreviated syntax of the optional chain and the optional operator, the appropriate pair of coordinates and magnitude of change is selected based on the direction. Then the corresponding coordinate is changed, the match values ​​are used, and the obtained new coordinate values ​​are assigned to the change object.

As a result, the function returns the changed values ​​of x and y coordinates in the form of an object.

Principle/Mechanics

The principle and mechanics of the CustomSwitch pattern have the following structure:

  1. The pattern is based on objects that make up custom cases (case blocks).

  2. The code becomes more readable because the object structure is used instead of conditionals if else.

  3. This pattern can be useful when you need to modify or perform other task actions.

The CustomSwitch pattern can override the use of conditions if else. If the standard was used switchThis could increase the number of lines of code and make it less readable. However, this pattern is able to simplify development by providing a more flexible alternative when solving a task.

Realization

Let’s create a changeArray function that will change the array using the functions and arguments passed.

/**
 * Изменяет входной массив с помощью переданных функций и аргументов
 * @param {array} list - входной массив
 * @param {string} func - имя функции для изменения массива
 * @param {any} argument - дополнительный аргумент для функции
 * @returns {array} - измененный массив
 * @throws {string} - если аргумент не является массивом
**/
function changeArray(list, func, argument) {
    if (!Array.isArray(list)) {
        throw `The argument is not an Array: ${list}`;
    }

    let [response, argumentsList] = [, [list, argument]];

    // код, выполняющий изменение массива

    return response;
}

Now let’s add callbacks to the callbacks object that will perform array operations.

let callbacks = {
    /**
     * Сливает два массива в один
     * @param {array} l1 - первый массив
     * @param {array} l2 - второй массив
     * @returns {array} - объединенный массив
    **/
    merge: (l1, l2) => l1.concat(l2),

    /**
     * Преобразует массив в вектор, заменяя значения на 0
     * @param {array} l - входной массив
     * @param {number} a1 - дополнительный аргумент
     * @returns {array} - массив-вектор со значениями 0
    **/
    vector: (l, a1) => callbacks.multiply(l, a1 ?? 0).map(v => [v]),

    /**
     * Преобразует массив в вектор, оставляя значения без изменений
     * @param {array} l - входной массив
     * @returns {array} - массив-вектор без изменений
    **/
    toVector: (l) => callbacks.vector(l, 1)
};

let args = {
    merge: argumentsList,
    vector: [list],
    toVector: [list]
};

We then call the appropriate callback with arguments if it exists, and return null if the callback doesn’t exist.

let callback = callbacks?.[func];
response = callback ? args?.[func] ? callback(...args[func]) : callback() : null;

Finally, after defining the functions, we can perform array operations:

console.log(changeArray([1, 2], 'merge', [2, 3]));
console.log(changeArray([1, 2], 'vector'));
console.log(changeArray([1, 2], 'toVector'));

Result:

[ 1, 2, 2, 3 ]
[ [ 0 ], [ 0 ] ]
[ [ 1 ], [ 2 ] ]
full code
function changeArray(list, func, argument) {
    if (!Array.isArray(list)) throw `The argument is not a Array: ${list}`;
    let [response, argumentsList] = [, [list, argument]];

    let callbacks = {
        mul: (l, a1) => l.map(v => v * a1),
        sub: (l, a1) => l.map(v => v - a1),
        merge: (l1, l2) => l1.concat(l2),
        vector: (l, a1) => callbacks.mul(l, a1 ?? 0).map(v => [v]),
        toVector: (l) => callbacks.vector(l, 1)
    }

    let args = {
        mul: argumentsList,
        sub: argumentsList,
        merge: argumentsList,
        vector: [list],
        toVector: [list]
    }

    let callback = callbacks?.[func];
    response = callback ? args?.[func] ? callback(...args[func]) : callback() : null;

    return response;
}


console.log(changeArray([1, 2], 'merge', [2, 3]));
console.log(changeArray([1, 2], 'vector'));
console.log(changeArray([1, 2], 'toVector'));

Conclusion

This article looked at the CustomSwitch pattern and its possible implementation. We considered the important aspects of working with this pattern and familiarized ourselves with examples of its application.

CustomSwitch is a useful tool for developers that allows you to create customizable switches using controls. This pattern is particularly useful in cases where you need to implement complex switch logic or when you want to further customize the appearance of the switch.

We have discussed several important points to consider when implementing CustomSwitch. First, we need to properly define the interface for our switch so that the user can easily use it in their code. Second, it is necessary to provide for the ability to customize the appearance of the switch through parameters or methods. Finally, for ease of use of the pattern, helper methods or classes can be provided to make it easier to work with CustomSwitch.

It’s important to note that understanding the basics of CustomSwitch comes with coding experience. The more you use this pattern and apply it to your projects, the better you will be able to master its capabilities and customize it to your needs.

At the end of the article, I hope you enjoyed reading it and gained some new knowledge about the CustomSwitch pattern. We hope you can successfully apply it in your projects and improve your software development skills.

Related posts