如何从类似的方法中去除冗余

How to remove redundancy from similar methods?

本文关键字:冗余 方法      更新时间:2023-09-26

关于如何在这个对象中删除方法的冗余,有什么创造性的建议吗?:

var ObjectCrud = {
    createByKey: function(object, word, new_key, new_val) {
        return iterativeFunction(object, function (key, obj) {
            if (key === word) {
                obj[new_key] = new_val;
            }
        });
    },
    readByKey: function(object, word) {
        var object_array = [];
        iterativeFunction(object, function (key, obj) {
            if (key === word) {
                 object_array.push(obj);
            }
        });
        if (object_array.length > 0) { return object_array; }
    },
    updateByKey: function(object, word, update) {
        return iterativeFunction(object, function (key, obj) {
            if (key === word) {
                obj[key] = update;
            }
        });
    },
    deleteByKey: function(object, word) {
        return iterativeFunction(object, function (key, obj) {
            if (key === word) {
                delete obj[key];
            }
        });
    },
    createByValue: function(object, word, new_key, new_val) {
        return iterativeFunction(object, function (key, obj) {
            if (obj[key] === word) {
                obj[new_key] = new_val;
            }
        });
    },
    readByValue: function(object, word) {
        var object_array = [];
        iterativeFunction(object, function (key, obj) {
            if (obj[key] === word) {
                 object_array.push(obj);
            }
        });
        if (object_array.length > 0) { return object_array; }
    },
    updateByValue: function(object, word, update) {
        return iterativeFunction(object, function (key, obj) {
            if (obj[key] === word) {
                obj[key] = update;
            }
        });
    },
    deleteByValue: function(object, word) {
        return iterativeFunction(object, function (key, obj) {
            if (obj[key] === word) {
                delete obj[key];
            }
        });
    }
}

我的代码为我工作,我只是觉得有一个更有表现力的方式来编写上面列出的方法。对于那些想知道这个对象会做什么的人来说,它的目标是在js对象上做与持久存储概念相关的操作。

好吧,你似乎想抽象你的iterativeFunction,其中总是有一个回调与if-test。

那么让我们为它写一个函数(实际上是两个,因为你一次比较键和一次值)。

function findKey(object, word, callback) {
    return iterativeFunction(object, function (key, obj) {
        if (key === word)
            callback(key, obj);
    });
}
function findValue(object, word, callback) {
    return iterativeFunction(object, function (key, obj) {
        if (obj[key] === word)
            callback(key, obj);
    });
}
var ObjectCrud = {
    createByKey: function(object, word, new_key, new_val) {
        return findKey(object, word, function(key, obj) {
            obj[new_key] = new_val;
        });
    },
    readByKey: function(object, word) {
        var object_array = [];
        findKey(object, word, function(key, obj) {
            object_array.push(obj);
        });
        if (object_array.length > 0) { return object_array; }
    },
    updateByKey: function(object, word, update) {
        return findKey(object, word, function(key, obj) {
            obj[key] = update;
        });
    },
    deleteByKey: function(object, word) {
        return findKey(object, word, function(key, obj) {
            delete obj[key];
        });
    },
    createByValue: function(object, word, new_key, new_val) {
        return findValue(object, word, function(key, obj) {
            obj[new_key] = new_val;
        });
    },
    readByValue: function(object, word) {
        var object_array = [];
        findValue(object, word, function(key, obj) {
            object_array.push(obj);
        });
        if (object_array.length > 0) { return object_array; }
    },
    updateByValue: function(object, word, update) {
        return findValue(object, word, function(key, obj) {
            obj[key] = update;
        });
    },
    deleteByValue: function(object, word) {
        return findValue(object, word, function(key, obj) {
            delete obj[key];
        });
    }
}

我们还看到回调被重复了很多。对于delete,它们实际上是完全相同的,其他的有重复的主体,但范围不同。此外,objectword参数以及findKeyiterativeFunction调用仍然被复制到任何地方(我实际上在上面的示例中使用了c&p)。

现在,我们可以针对这一点,通过应用一点函数式编程,或者确切地说是部分应用程序,使一切变得更简洁:

function makefinder(compare) {
    return function makeCrud(callback) {
        return function(object, word, arg1, arg2) {
            return iterativeFunction(object, function (key, obj) {
                if (compare(key, obj, word))
                    callback(key, obj, arg1, arg2);
            });
        };
    };
}
var findKey = makeFinder(function(key, _, word) { return key===word; });
var findValue = makeFinder(function (key, obj, word) { return obj[key] === word; });
function create    (_,   obj, new_key, new_val) { obj[new_key] = new_val; }
function read      (key, obj, object_array)     { object_array.push(obj); }
function update    (key, obj, update)           { obj[key] = update; }
function deleteProp(key, obj)                   { delete obj[key]; }
function makeReader(finder) {
    var reader = finder(read);
    return function(object, word) {
        var array = [];
        reader(object, word, array);
        if (array.length) return array;
    };
}
var ObjectCrud = {
    createByKey: findKey(create),
    readByKey:   makeReader(findKey),
    updateByKey: findKey(update),
    deleteByKey: findKey(deleteProp),
    createByValue: findValue(create),
    readByValue:   makeReader(findValue),
    updateByValue: findValue(update),
    deleteByValue: findValue(deleteProp)
};

当然你也可以创建ObjectCrud通过循环在一个矩阵与[Key, Value][create, read, update, delete]在另一个维度…