一屏之地,尽收眼底!对的!要的就是短小精悍!c++
翻开项目的代码,到处可见成百上千行的函数,函数体里面switch-case、if、for等交错在一块儿,一眼望不到头的感受。有些变态的函数,长度可能得按千米计算了。神啊,请赐予我看下去的勇气吧!先不论逻辑如何,首先这长度直接就把人给吓到了。这些超大号函数是怎么来得呢?redis
这些超长的函数,给咱们形成了很大的麻烦:阅读代码找BUG几乎是不可能的事情,没有调试器估计撞墙的心都有了;重复代码形成修改困难,漏掉任何一处早晚是要出问题的;各个层次的代码混在一块儿,阅读代码至关吃力,人的临时记忆是有限的,不断在各个层次之间切换,一下子就给绕晕了。ide
更多内容:http://game-lab.org/posts/zoc-cleancode-5/函数
解决这些问题最重要的就是要保持函数的短小,短小的函数阅读起来要好得多,同时短小的函数意味着较好的封装。下面谈谈关于函数,应该遵循的一些原则:post
在编码之道:取个好名字中已经介绍过,好名字的重要性,再也不赘述。ui
bool isBossNpc(); void summonNpc(int id); void summonNpc(int id, int type); void summonNpc(int id, int state, int type); // 还能记得参数顺序吗? void showCurrentEffect(int state, bool show); // Bad!!! void showCurrentEffect(int state); // Good!! void hideCurrentEffect(int state); // 新加个函数也没多难吧? bool needWeapon(DWORD skillid, BYTE& failtype); // Bad!!!
bool RedisClient::connect(const std::string& host, uint16_t port) { this->host = host; this->port = port; this->close(); try { redis_cli = new redis::client(host, port); return true; } catch (redis::redis_error& e) { redis_cli = NULL; std::cerr << "error:" << e.what() << std::endl; return false; } return false; }
重复是一些邪恶的根源!!!this
BAD:编码
bool saveBinary(type, data) { switch (type) { case TYPE_OBJECT: .... break; case TYPE_SKILL: ... break; .... } } bool needSaveBinary(type) { switch (type) { case TYPE_OBJECT: return true; case TYPE_SKILL: ... break; .... } }
class BinaryMember { BinaryMember* createByType(type){ switch (type) { case TYPE_OBJECT: return new ObjectBinaryMember; case TYPE_SKILL: return new SkillBinaryMember; .... } virtual bool save(data); virtual bool needSave(data); }; class ObjectBinaryMember : public BinaryMember { bool save(data){ .... } bool needSave(data){ .... } };")))
上面提到的原则,若要理解的更加深入,建议去阅读《代码整洁之道》,里面有许多详尽的例子,对于写过几年代码的人来讲,总会发现一些本身所在项目常常犯的毛病。spa
知道了这些原则,咱们应该这样作:调试
当在添加新函数的时候:
重构现有的函数,有下面状况的,见一个消灭一个: