记一次代码重构

2,543 阅读2分钟

前言

最近在和一位后端大神写一个邮件通知平台,大神看到我的代码以后气不打一处来,简直不能看。资历尚浅的我开始了第一次代码重构。

原来的样子

function receiverList(callback) {
    $.ajax({
        method: "GET",
        url: server + "receiver/list",
    }).done(function (data) {
        if (data.status === 200) {
            let {result} = data;
            callback.call(this, result)
        } else {
            alert(404)
        }
    });
}

function addReceiver(name, email, callback) {
    $.ajax({
        method: 'POST',
        url: server + "receiver/add",
        data: {
            name: name,
            email: email
        },
    }).done(function (data) {
        callback.call(this, data);
    });
}

function deleteReceiver(id, callback) {
    $.ajax({
        method: 'GET',
        url: server + "receiver/delete",
        data: {
            id: id
        },
    }).done(function (data) {
        callback.call(this, data);
    });
}

function groupList(callback) {
    $.ajax({
        method: "GET",
        url: server + "group/list",
    }).done(function (data) {
        if (data.status === 200) {
            let {result} = data;
            callback.call(this, result)
        } else {
            alert(404)
        }
    });

}

function addReceiverGroup(groupName, receiverGroupIds, callback) {
    $.ajax({
        method: 'POST',
        url: server + "group/add",
        data: {
            name: groupName,
            receiverId: receiverGroupIds
        },
        traditional: true
    }).done(function (data) {
        callback.call(this, data);
    });
}

function deleteReceiverGroup(id, callback) {
    $.ajax({
        method: 'GET',
        url: server + "group/delete",
        data: {
            id: id
        },
    }).done(function (data) {
        callback.call(this, data);
    });
}

function messageList(callback) {
    $.ajax({
        method: "GET",
        url: server + "message/list",
    }).done(function (data) {
        if (data.status === 200) {
            let {result} = data;
            callback.call(this, result)
        } else {
            alert(404)
        }
    });
}

function addMessage(subject, content, callback) {
    $.ajax({
        method: 'POST',
        url: server + "message/add",
        data: {
            subject: subject,
            content: content
        },
    }).done(function (data) {
        callback.call(this, data);
    });
}

function deleteMessage(id, callback) {
    $.ajax({
        method: 'GET',
        url: server + "message/delete",
        data: {
            id: id
        },
    }).done(function (data) {
        callback.call(this, data);
    });
}

这是自己封装的用于前后端数据交互的一些代码,全部采用的都是函数调用的形式,啰啰嗦嗦重复的代码不少,现在自己看起来也很别扭。 这些函数负责的是接收者、接收组和消息的增删查。

重构过程

1. 由函数变对象

一次次调用函数,每一个函数都负责一个功能,实际上他们却存在联系,接收者有增删查,接受组有增删查,消息依旧有增删查,而我却写了 9 个函数。于是,我把接收者看成一个对象,在接收者上有三个可以调用的方法,分别是 add ,query ,delete。

代码变成了这个样子,这里只以接收者为例。

let receiver = {
    list(callback) {
        $.ajax({
            method: "GET",
            url: server + "receiver/list",
        }).done(function (data) {
            if (data.status === 200) {
                let {result} = data;
                callback.call(this, result)
            } else {
                alert(404)
            }
        });
    },
    add(name, email, callback) {
        $.ajax({
            method: 'POST',
            url: server + "receiver/add",
            data: {
                name: name,
                email: email
            },
        }).done(function (data) {
            callback.call(this, data);
        });
    },
    delete(id, callback) {
        $.ajax({
            method: 'GET',
            url: server + "receiver/delete",
            data: {
                id: id
            },
        }).done(function (data) {
            callback.call(this, data);
        });
    }
    
};

现在调用的时候就可以直接,receiver.add(),看起来就比原来的冗长函数名舒服多了,表意上也直接看出来是接收着的添加操作。

2. 从最简单的开始抽象出公共操作

我发现,无论是 receiver,receiverGroup 还是 message 都利用了 ajax 传输数据,可是却在每个对象里面都重复的写那几句话,我需要一个 ajax 对象。

经过观察我发现,查询和删除操作所需要的传参最少,每一个对象的查询和删除可以说一模一样,现在这样的形式根本没有做到代码复用,有重复的代码说明就可以进行简化,在添加的时候传参相对于前两者较为复杂,暂时先不做改变。

let ajax = {
    ajaxQuery(url, callback) {
        $.ajax({
            method: "GET",
            url: server + url,
        }).done(function (data) {
            if (data.status === 200) {
                let {result} = data;
                callback.call(this, result)
            } else {
                alert(404)
            }
        });
    },
    ajaxDelete(id, url, callback) {
        $.ajax({
            method: 'GET',
            url: server + url,
            data: {
                id: id
            },
        }).done(function (data) {
            callback.call(this, data);
        });
    }
}

因为每次 ajax 要查询的 server 地址是不同的,所以传参中必须要有 url 。

let receiver = {
    list(callback) {
        let url = 'receiver/list';
        ajax.ajaxQuery(url, callback);
    },
    delete(id, callback) {
        let url = 'receiver/delete';
        ajax.ajaxDelete(id, url, callback);
    }
};

现在看起来思路清晰多了,代码即注释,哈哈哈。

3. 继续优化

有了上面的代码,我发现添加操作也不复杂了,它和其他两个方法唯一不同的就是要传递数据,那我直接把不同 data 对象存好了,直接传就好了。所以 ajax 的添加方法和查询删除没有很大差别,之前认为复杂的其实并不复杂。

ajaxAdd(url, data, callback) {
        $.ajax({
            method: 'POST',
            url: server + url,
            data: data,
        }).done(function (data) {
            callback.call(this, data);
        });
    },

add 的时候只需把数据处理一下就好了,也没有什么难的,思路渐渐清晰起来,复杂的也简单化了。

let receiver = {
    list(callback) {},
    add(name, email, callback) {
        let url = 'receiver/add';
        let data = {
            name: name,
            email: email
        }
        ajax.ajaxAdd(url, data, callback)
    },
    delete(id, callback) {}
};

现在的样子

let receiver = {
    list(callback) {
        let url = 'receiver/list';
        ajax.ajaxQuery(url, callback);
    },
    add(name, email, callback) {
        let url = 'receiver/add';
        let data = {
            name: name,
            email: email
        }
        ajax.ajaxAdd(url, data, callback)
    },
    delete(id, callback) {
        let url = 'receiver/delete';
        ajax.ajaxDelete(id, url, callback);
    }
};

let receiverGroup = {
    list(callback) {
        let url = 'group/list';
        ajax.ajaxQuery(url, callback);
    },
    add(groupName, receiverGroupIds, callback) {
        let url = 'group/add';
        let data = {
            name: groupName,
            receiverId: receiverGroupIds
        }
        ajax.ajaxAdd(url,data,callback)
    },
    delete(id, callback) {
        let url = 'group/delete';
        ajax.ajaxDelete(id, url, callback);
    }
}

let message = {
    list(callback) {
        let url = 'message/list';
        ajax.ajaxQuery(url, callback);
    },
    add(subject, content, callback) {
        let url = 'message/add';
        let data = {
            subject: subject,
            content: content
        };
        ajax.ajaxAdd(url,data,callback);
    },
    delete(id, callback) {
        let url = 'message/delete';
        ajax.ajaxDelete(id, url, callback)
    }
}

let ajax = {
    ajaxQuery(url, callback) {
        $.ajax({
            method: "GET",
            url: server + url,
        }).done(function (data) {
            if (data.status === 200) {
                let {result} = data;
                callback.call(this, result)
            } else {
                alert(404)
            }
        });
    },
    ajaxAdd(url, data, callback) {
        $.ajax({
            method: 'POST',
            url: server + url,
            data: data,
        }).done(function (data) {
            callback.call(this, data);
        });
    },
    ajaxDelete(id, url, callback) {
        $.ajax({
            method: 'GET',
            url: server + url,
            data: {
                id: id
            },
        }).done(function (data) {
            callback.call(this, data);
        });
    }
}

后记

大神说这样看起来舒服多了,心里没有刚刚那么堵得慌了,中午都能多吃一碗大米饭呢。

后端大神知识面很广,每次都是分分钟帮我解决 bug,这里宣传下大神的掘金 LeopPro