副标题:我曾是他们的坚定信仰者,但现在我已经皈依了。
发布时间:2020年8月18日 - 6分钟阅读
如果你已经做了十几年的代码,你可能会有一些你坚信的喜欢的风格,并且用你的论点来捍卫它们直到最后。 以下是我曾经坚定地坚持过的一些,但现在我想我必须放手了。
1. 用m或this来表示成员变量
规则。为了区分成员变量和局部变量,请使用以下任何一种方法
- 匈牙利符号的使用,即mMemberVariable与localVariable。其中m代表成员变量。
- this的使用即this.memberVariable与localVariable。
过去的原因
原因是我们在阅读代码的时候,不用看它们的声明,就可以很容易知道它们是成员变量还是局部变量。
class MyClass {
var mMember = "member"
fun doSomething() {
val local = "local"
println(this.mMember)
println(local)
}
}
现在
如果是现代IDE,就不再需要这种基于文字的区分了。请看下面同样的代码,它会自动给它们不同的颜色。
变量的不同颜色
2. 始终明确声明公开、保护或私有
规则:在一个类中,所有的变量和函数都需要明确说明是public、private还是protected。不要假设默认状态。
- 需要明确说明类型,如
String或Int。 - 要说明是
private还是public。
public class MyClass {
public val publicVariable: String = "100"
private fun privateFunction() {}
public fun publicFunction() {}
}
过去的原因
这是为了避免有人错误地访问这些函数或变量,即如果一个函数没有被声明,用户可能不知道它的默认状态是public还是private。
现在
在现代IDE中,我们不需要明确声明默认状态,比如Kotlin是public的。用户不会不小心弄错默认状态,因为自动完成只会显示公共方法。所以不可能有人会混淆什么是默认状态。
私有函数不会出现在自动完成时。
如果有任何错误的用法(例如访问private函数),它不会在编译时才出错。它会立即出错,并给出明确的信息。
3. 明确声明一个变量类型总是
规则:所有的变量都应该用其类型来声明,即使它的值很清楚,例如,需要明确地说明类型,如String或Int。所有的变量都应该用它的类型来声明,即使它的值很清楚,例如:需要明确地说明类型,例如:String或Int。
public class MyClass {
public val publicVariable: String = "100"
private fun privateFunction() {}
public fun publicFunction() {}
}
过去的原因
这是为了避免有人错误地访问这些函数或变量,例如变量被分配到了错误的类型,从而导致编译错误。
现在
如果是现代编程语言,如果一个变量的类型是可以推断的,是不含糊的,那么就不需要明确地说明它的类型。这就是所谓的类型推理。现在很多现代语言中都有这种功能。
如果有任何错误的赋值等,它不会在编译时才出错。它立即会以一个明确的信息出错。
10 + MyClass().publicVairable会立即出错,因为Int和String不能加在一起。
4. 成员变量应该永远是私有的
规则。所有成员变量都应该是私有的,通过getter和setter访问,适用于需要从外部设置或获取的成员变量。
public class MyClass{
private var member = "member";
public fun getMember(): String {
return member;
}
public fun setMember(value: String) {
member = value;
}
}
过去的原因
如果我们把它公开为设置和获取,在我们需要在它们被设置或获取时执行一些操作时,我们需要改变所有访问它的代码。 所以,如果我们只限制在getter和setter上,我们就可以控制它,例如
class MyClass{
private var member = "member";
fun getMember(): String {
println("Setting member")
return member;
}
fun setMember(value: String) {
println("Setting member with $value")
member = value;
}
}
现在
在现代语言中(例如Kotlin),我们可以很容易地在需要的时候在变量上插入getter或setter,而不需要明确地有两个不同的函数来设置和获取。
所以我们可以像下面的代码一样,不需要在类中增加setter和getter函数。
class MyClass {
var member = "member"
}
当我们需要对setter或getter做一些事情时,我们可以很容易地添加它们,而不需要改变访问成员的代码。
class MyClass {
var member = "member"
get(): String {
println("Setting member")
return field
}
set(value: String) {
println("Setting member with $value")
field = value
}
}
5. 开始和结束的大括号应该对齐。
规则。所有的大括号都应该排列在同一列,这样我们就可以很容易地找到它们的对子,例如
class MyClass
{
private var member: String = "member"
fun doSomething(state: Boolean)
{
val local = "local"
println(member)
println(local)
}
}
过去的原因
原因是通过垂直观察,我们可以很容易地找到它们的对子,从而知道函数的范围在哪里。
现在
在新的IDE中,只要代码看起来整洁,我们就不再需要将开始和结束的大括号对齐在同一列上。
class MyClass {
private var member: String = "member"
fun doSomething(state: Boolean) {
val local = "local"
println(member)
println(local)
}
}
这是因为我们可以轻松地折叠或展开它们,如下图所示。
轻松扩展或折叠代码范围
想了解更多关于卷曲括号的知识,请看下文。
它从哪里来,怎么样,能不能持久?
6. 所有的缩进都使用制表符。
规则:所有的缩进都使用制表符,而不是使用空格。
过去的原因
例如,下面的例子显示,当使用空格时,需要打很多次字
旧的文本编辑器,需要输入每一个空格。
现在
有了IDE,它会自动为我们缩进适当数量的空格。而有了空格,也能保证所有的代码在不同的用户环境下看起来一致。
现代IDE,直到执行自动缩进的空间
7. 使用分号结束代码语句
规则:当代码语句结束时,必须用分号。当结束一个代码语句时,需要用分号。
过去的原因
这是自古编程语言甚至C和C++、Java等都需要的,让解析器识别已经结束。部分原因是我们有80列,因此当需要为一条语句多写代码时,我们可以为一条语句写几行代码。
现在
随着新的现代语言(如Kotlin)的出现,我们不再需要编写很长的语句(例如,我们可以将变量命名得更短,减少缩进)。 即使我们需要编写较长的语句,我们也不再受制于8列(虽然不是一个好的做法)。另外,我们这几天的显示器都比较长😝。
照片:Fotis Fotopoulos on Unsplash
所以,如果一种语言不允许使用分号,就去做吧!
如果想进一步了解第4-7项,可以阅读下面的内容。
几十年的小事之争,还会结束吗?
通过改变我对上述7种编码方式的看法,我将我的代码修改如下。
世界是不断变化的。过去需要的东西可能已经不适用了。随着技术和工具的发展,我们应该随时重新评估曾经的规则,并不断进步。
感觉自己年轻了许多。谢谢你的阅读