Библиотека JavaScript для уведомления наблюдателей об изменениях


Фон

В прошлом году, когда я был еще войти в начале неизменность и чистые функции и еще много чего я создал библиотеку для сообщества под названием obj-watcher.

Эта библиотека очень проста - она позволяет зарегистрировать объект, и, чтобы получить уведомление при изменении случится на этот объект через заданный API.

Проблема

Сначала все было нормально. Я получил максимальный балл за все и то один день ... CodeClimate изменили способ, которым они оценивают код и они оценили мой проект как С.

Это не есть хорошо. По их мнению, мой проект трудно поддерживать, потому что он имеет высокую когнитивную нагрузку. Я нахожу это трудно поверить, но я абсолютно предвзята.

Чего я хочу?

Весь код прокомментирован через jsdoc и я знаю, что я мог бы улучшить некоторые функции. Но что я действительно хочу, - это некоторую обратную связь на мой код. Я хотел бы знать, если это действительно так трудно для кого-то еще понять ( ПС, убрал комментарии ):

const isFunction = require("lodash.isfunction");

const errors = require("./errors.js");
const callbackNotAFunction = errors.callbackNotAFunction;
const objectAlreadyWatched = errors.objectAlreadyWatched;
const objectNotWatched = errors.objectNotWatched;

const watcherFactory = () => {


    const watchMap = new Map();

    const watch = (objId, obj) => {
        if (isObjWatched(objId))
            throw objectAlreadyWatched(objId);

        watchMap.set(objId, {
            obj: obj,

            onChange: () => {}
        });
    };


    const unwatch = objId => {
        if (!isObjWatched(objId))
            throw objectNotWatched(objId);
        watchMap.delete(objId);
    };


    const get = objId => {
        if (!isObjWatched(objId))
            throw objectNotWatched(objId);
        return Object.assign({}, watchMap.get(objId).obj);
    };


    const set = (objId, newObj) => {
        if (!isObjWatched(objId))
            throw objectNotWatched(objId);

        const entry = watchMap.get(objId);
        const oldObj = Object.assign({}, entry.obj);
        entry.obj = Object.assign({}, newObj);
        entry.onChange(oldObj, entry.obj);
    };


    const onChange = (objId, callback) => {
        if (!isObjWatched(objId))
            throw objectNotWatched(objId);

        if (!isFunction(callback))
            throw callbackNotAFunction(objId);

        const entry = watchMap.get(objId);
        entry.onChange = callback;
    };


    const reset = () => {
        watchMap.clear();
    };

    const isObjWatched = objName => watchMap.has(objName);

    return Object.freeze({
        watch,
        unwatch,
        onChange,
        get,
        set,
        reset
    });
};

module.exports = watcherFactory();

Штаты CodeClimate этот код сложно из-за 2 причин:

  • Функция watcherFactory имеет 47 строк кода (превышает 25 разрешено). Рассмотреть возможность рефакторинга.
  • Функция watcherFactory есть когнитивные сложности 12 (превышает 5 допускается). Рассмотреть возможность рефакторинга.

Здесь я использую хорошо зарекомендовавший объект шаблона "фабрика" от Дугласа Крокфорда, где у меня есть функция, которая создает и возвращает объект с методами.

Эта функция все внутри и является стандартным способом определения публичного и частного переменных посредством блокады и заключения.

Однако, после прочтения статьи CodeClimate о когнитивной сложности ( который я также рекомендую ):

https://docs.codeclimate.com/docs/cognitive-complexity

Я думаю, что их система имеет проблемы с фабрикой функции, потому что она кажется им как нормальная функция, которая является слишком большой. Таким образом, их система делает как бы есть смысл... мне интересно, если есть способ я могу реструктурировать это, чтобы сделать его более очевидным и выиграть обе битвы.

Что вы думаете?



Комментарии
1 ответ

Примечание: этот попал опечатка, вместо того, чтобы исправить то, что я сказал ниже: это не должно было быть немедленно исполнено.

Зачем тебе что-то, что эффективно в жизни? Вы не можете просто использовать:

const watchMap = new Map();

const watch = (objId, obj) => {
if (isObjWatched(objId))
throw objectAlreadyWatched(objId);

watchMap.set(objId, {
obj: obj,

onChange: () => {}
});
};

// ...

module.exports = {
watch,
unwatch,
onChange,
get,
set,
reset
};

0
ответ дан 11 марта 2018 в 08:03 Источник Поделиться