Blog

Blog

PHODAL

用code climate来clean code与重构

  • 当你写了一大堆代码,你没有意识到里面有一大堆重复。
  • 当你写了一大堆测试,却不知道覆盖率有多少。

这就是个问题了,于是偶然间看到了一个叫code climate的网站。

Code Climate

Code Climate consolidates the results from a suite of static analysis tools into a single, real-time report, giving your team the information it needs to identify hotspots, evaluate new approaches, and improve code quality.

Code Climate整合一组静态分析工具的结果到一个单一的,实时的报告,让您的团队需要识别热点,探讨新的方法,提高代码质量的信息。

简单地来说:

  • 对我们的代码评分
  • 找出代码中的坏味道

于是,我们先来了个例子

Rating | Name | Complexity | Duplication | Churn | C/M | Coverage | Smells --------|------|--------------|-------------|----------|---------|--------------------- A | lib/coap/coap_request_handler.js | 24 | 0 | 6 | 2.6 | 46.4% | 0 A | lib/coap/coap_result_helper.js | 14 | 0 | 2 | 3.4 | 80.0% | 0 A | lib/coap/coap_server.js | 16 | 0 | 5 | 5.2 | 44.0% | 0 A | lib/database/db_factory.js | 8 | 0 | 3 | 3.8 | 92.3% | 0 A | lib/database/iot_db.js | 7 | 0 | 6 | 1.0 | 58.8% | 0 A | lib/database/mongodb_helper.js | 63 | 0 | 11 | 4.5 | 35.0% | 0 C | lib/database/sqlite_helper.js | 32 | 86 | 10 | 4.5 | 35.0% | 2 B | lib/rest/rest_helper.js | 19 | 62 | 3 | 4.7 | 37.5% | 2 A | lib/rest/rest_server.js | 17 | 0 | 2 | 8.6 | 88.9% | 0 A | lib/url_handler.js | 9 | 0 | 5 | 2.2 | 94.1% | 0

分享得到的最后的结果是:

Coverage
Coverage

代码的坏味道

于是我们就打开lib/database/sqlite_helper.js,因为其中有两个坏味道

Similar code found in two :expression_statement nodes (mass = 86)

在代码的 lib/database/sqlite_helper.js:58…61 < >

SQLiteHelper.prototype.deleteData = function (url, callback) {
    'use strict';
    var sql_command = "DELETE FROM  " + config.table_name + "  where " + URLHandler.getKeyFromURL(url) + "=" + URLHandler.getValueFromURL(url);
    SQLiteHelper.prototype.basic(sql_command, callback);

lib/database/sqlite_helper.js:64…67 < >

SQLiteHelper.prototype.getData = function (url, callback) {
    'use strict';
    var sql_command = "SELECT * FROM  " + config.table_name + "  where " + URLHandler.getKeyFromURL(url) + "=" + URLHandler.getValueFromURL(url);
    SQLiteHelper.prototype.basic(sql_command, callback);

只是这是之前修改过的重复。。

原来的代码是这样的

SQLiteHelper.prototype.postData = function (block, callback) {
    'use strict';
    var db = new sqlite3.Database(config.db_name);
    var str = this.parseData(config.keys);
    var string = this.parseData(block);

    var sql_command = "insert or replace into " + config.table_name + " (" + str + ") VALUES (" + string + ");";
    db.all(sql_command, function (err) {
        SQLiteHelper.prototype.errorHandler(err);
        db.close();
        callback();
    });
};

SQLiteHelper.prototype.deleteData = function (url, callback) {
    'use strict';
    var db = new sqlite3.Database(config.db_name);
    var sql_command = "DELETE FROM  " + config.table_name + "  where " + URLHandler.getKeyFromURL(url) + "=" + URLHandler.getValueFromURL(url);
    db.all(sql_command, function (err) {
        SQLiteHelper.prototype.errorHandler(err);
        db.close();
        callback();
    });
};

SQLiteHelper.prototype.getData = function (url, callback) {
    'use strict';
    var db = new sqlite3.Database(config.db_name);
    var sql_command = "SELECT * FROM  " + config.table_name + "  where " + URLHandler.getKeyFromURL(url) + "=" + URLHandler.getValueFromURL(url);
    db.all(sql_command, function (err, rows) {
        SQLiteHelper.prototype.errorHandler(err);
        db.close();
        callback(JSON.stringify(rows));
    });
};

说的也是大量的重复,重构完的代码

SQLiteHelper.prototype.basic = function(sql, db_callback){
    'use strict';
    var db = new sqlite3.Database(config.db_name);
    db.all(sql, function (err, rows) {
        SQLiteHelper.prototype.errorHandler(err);
        db.close();
        db_callback(JSON.stringify(rows));
    });

};

SQLiteHelper.prototype.postData = function (block, callback) {
    'use strict';
    var str = this.parseData(config.keys);
    var string = this.parseData(block);

    var sql_command = "insert or replace into " + config.table_name + " (" + str + ") VALUES (" + string + ");";
    SQLiteHelper.prototype.basic(sql_command, callback);
};

SQLiteHelper.prototype.deleteData = function (url, callback) {
    'use strict';
    var sql_command = "DELETE FROM  " + config.table_name + "  where " + URLHandler.getKeyFromURL(url) + "=" + URLHandler.getValueFromURL(url);
    SQLiteHelper.prototype.basic(sql_command, callback);
};

SQLiteHelper.prototype.getData = function (url, callback) {
    'use strict';
    var sql_command = "SELECT * FROM  " + config.table_name + "  where " + URLHandler.getKeyFromURL(url) + "=" + URLHandler.getValueFromURL(url);
    SQLiteHelper.prototype.basic(sql_command, callback);
};

重构完后的代码比原来还长,这似乎是个问题~~

关于我

Github: @phodal     微博:@phodal     知乎:@phodal    

微信公众号(Phodal)

围观我的Github Idea墙, 也许,你会遇到心仪的项目

QQ技术交流群: 321689806

新书《前端架构:从入门到微前端》

《前端架构:从入门到微前端》是一本围绕前端架构的实施手册,从基础的架构规范,到如何设计前端架构,再到采用微前端架构拆分复杂的前端应用。本书通过系统地介绍前端架构世界的方方面面,来帮助前端工程师更好地进行系统设计。

前端架构包含以下五部分内容:

  • 设计:讲述了架构设计的模式,以及设计和制定前端工作流。
  • 基础:通过深入构建系统、单页面应用原理、前端知识体系等,来构建出完整的前端应用架构体系。
  • 实施:通过与代码结构的方式,介绍如何在企业级应用中实施组件化架构、设计系统和前后端分离架构。
  • 微前端:引入6种微前端的概念,以及如何划分、设计微前端应用,并展示了如何实现这6种微前端架构。
  • 演进:提出更新、迁移、重构、重写、重新架构等架构演进方式,来帮助开发人员更好地设计演进式架构。
comment

Feeds

RSS / Atom

最近文章

关于作者

Phodal Huang

Developer, Consultant, Writer, Designer

ThoughtWorks 高级咨询师

工程师 / 咨询师 / 作家 / 设计学徒

开源深度爱好者

出版有《前端架构:从入门到微前端》、《自己动手设计物联网》、《全栈应用开发:精益实践》

联系我: h@phodal.com

微信公众号: 与我沟通

标签