一、前言
我学习编程就像在摸黑,没有过系统的学习,只能依赖不断的尝试和错误,一边研究开源框架,一边摸石头过河。发现同事们也都是在同一条船上,一头雾水。所以,我打算把最近读到的书籍和自己摸索的代码经验结合起来,做一个总结。这不仅能帮助我自己成长,也希望能和大家分享,一起在这个操🥚的世界中中相互启发、共同进步。当然为什么会写出糟糕的代码,自身的因素或许不是主要原因,为了赶进度、为了快点完成、老板的任务罢了。但是我们自己永远是最棒的,嘻嘻嘻。如果您有任何疑问、对文章写的不满意、发现错误或者有更好的方法,欢迎在评论、私信或邮件中提出,非常感谢您的支持。🙏
如果可以你可以去看看《Clear Code》这本书
二、名副其实
在大多数时候变量、函数、类的名称,已经告诉你了他们的职责。而不需要通过上下文,或者注释来推断其作用。
arduino
private Timer timer; // 这是什么?
arduino
private Timer heartbeatReportTimer; // 清楚地表达
选择体现本意的名称能让人更容易理解和修改代码。
scss
if (chatInputMsg.getInputState() == 1) {
handler.removeMessages(1004);
handler.sendEmptyMessageDelayed(1004, 5000);
}
是什么导致这段代码难以让人理解的?
- 在判断中"1"代表着什么
- 1004的含义是
- 为什么是5000
在这一段代码中,这几个问题的答案没有任何的体现,你只能去上下文中,甚至可能需要去查阅对应的状态码。
我们稍作修改
scss
if (chatInputMsg.isInputting()) {
handler.removeMessages(CANCEL_INPUTTING_CODE);
handler.sendEmptyMessageDelayed(CANCEL_INPUTTING_CODE, DELAY_CANCEL_INPUTTING_TIME);
}
一切都没有变,除了没有奇怪的数字,代码变得明确多了。
三、避免误导
我不知道各位有没有遇到过奇奇怪怪的反人类命名。我是遇到过的。
判断一下两个变量的类型~
see_num
comment_num
嘻嘻嘻,答案是⬇️
arduino
private String comment_num;
private String see_num;
相信你看到这,会觉得非常的头疼了,但是如果告诉你,为了兼容老旧的版本,出现了
arduino
private String comment_num_text;
private String see_num_text;
爆炸!💥。显然当使用者看到comment_num
的时候都想当然的觉得这是一个int
,但实际上这却是一个String
,最后不得不出现了comment_num、comment_num_text,这样组合奇怪的声明。
当然"oO0,ilI|",当极其相似的字母、符号、数字组合到一起的时候,你就只能指望你的编译器字体能让你区分出来了。不要用这些玩意组合到一起!
arduino
class classTest{
private String stringBoolean;
}
当然也不要用,特定语言的特定名词,来作为你命名的一部分。
包括一些特殊含义的词,应该只用在特殊的地方,比如List。相信所有程序只要看到List
,脑子中浮现的肯定是常用语言的List
结构(是的,我甚至想不出什么好的表达来说List
,列表?),所以你肯定不希望看到一个类、变量、函数,顶着List
的名头,做着其他的事情吧?(但是我遇到过!)
四、做有意义的区分
typescript
public void setParams(String param1, String param2, String param3){}
这行代码不用评判,你都能骂上好久。完全没有提供正确信息;没有提供导向作者意图的线索。但是!它有可能是你享受着编译器的快捷,使用快速生成,促成的代码!所以记得修改你使用快捷生成,生成的代码。
scss
getActiveAccount();
getActiveAccountData();
getActiveAccountInfo();
"请选择你调用的函数"。谁能知道该调用哪个函数呢?区分你的函数名称,让人可以直观的鉴别。
- 不要在参数名中使用param
- 不要在显而易见的字符串中使用String,名字一定是一个字符串,不用叫做nameString
- Family 和 FamilyObject 大部分时候两者是没有实际区别的
五、易于搜索的名称
别用一些显而易见的数字,字母来作为名称。CANCEL_INPUTTING_CODE
是一个非常好搜索的名称,但是如果使用"1",我相信你能搜索到一千个?一万个?
"若变量或常量可能在代码中多处使用,则应赋其以便于搜索的名称"
六、成员前缀
有时候,会有人告诉你,成员变量使用mXXXX的形式来表达。我想说的是,没必要。
arduino
private String mFirstName;
private String mSex;
private String mAdress;
private String mLast;
你可以察觉到,多出现几次后,你就不再关注"m",你会下意识的寻找"m"后的单词,只看到名称中有意义的部分。"最终,前缀变作了不入法眼的废料"
七、多义词的单一概念/单一概念的多词
"给每个抽象概念选一个词,并且一以贯之"。例如fetch、retrieve和get这在同一个类中出现,会让你感到很困惑,因为他们某些时候适用于相同的场景。对于某些行为你应该使用并规定某种称呼。
函数名称应当独一无二,而且要保持一致,你不能在A类中,获取列表叫getUserList(),在B类中获取列表叫getUsers(),诸如此类。
再者,遵循一词一意,避免将同一单词用于不同目的。假设我们有一个用于管理图形对象的类,这个类中包含了一个方法 draw
。在这个上下文中,draw
方法的目的是在屏幕上渲染图形。现在,假设我们要添加一个新的功能来调整图形的大小,特别是要将图形的尺寸缩小。某些开发者可能会考虑使用 draw
作为这个新方法的名称,因为这个词在英语中也有"拉伸"或"拖动"的含义,可以被理解为改变大小的意思。
但是,尽管 draw
这个词在不同的上下文中确实有不同的意义,但在这个图形管理类的上下文中,draw
已经被用来表示渲染图形。使用相同的 draw
方法名来表示改变图形大小会导致混淆。在这种情况下,更合适的方法名可能是 resize
或 scale
,因为这些名称更准确地描述了方法的功能,避免了可能的误解和混淆。
八、总结
"如果名称改得更好,那大家真的会感激你。"
如果您有任何疑问、对文章写的不满意、发现错误或者有更好的方法,欢迎在评论、私信或邮件中提出,非常感谢您的支持。🙏