这绝对是主观的,但我想尽量避免它变成争论。我认为如果人们恰当地对待它,这将是一个有趣的问题。

这个问题的想法来自于我对“你最讨厌的语言的哪五件事?”问题的回答。我认为c#中的类在默认情况下应该是密封的——我不会把我的理由放在这个问题上,但我可能会写一个更完整的解释来回答这个问题。我对评论中的讨论热度感到惊讶(目前有25条评论)。

那么,你有什么有争议的观点?我宁愿避免那些基于相对较少的基础而导致相当宗教的事情(例如,大括号放置),但例如可能包括“单元测试实际上并没有多大帮助”或“公共字段确实是可以的”之类的事情。重要的是(至少对我来说)你的观点背后是有理由的。

请提出你的观点和理由——我鼓励人们投票给那些有充分论证和有趣的观点,不管你是否恰好同意这些观点。


当前回答

开发80%是关于设计,20%是关于编码

我认为开发者应该将80%的时间用于设计细节,即他们将要构建的内容,而只有20%的时间用于编写他们所设计的内容。这将产生几乎零错误的代码,并在测试-修复-重新测试周期中节省大量时间。

过早地进入金属(或IDE)就像过早的优化,这被认为是万恶之源。深思熟虑的前期设计(我说的不一定是庞大的设计文档,简单的白板图纸也可以)会比编码和修改产生更好的结果。

其他回答

布尔变量只能用于布尔逻辑。在所有其他情况下,使用枚举。


布尔变量用于存储只能有两个可能值的数据。使用它们所产生的问题经常被忽视:

程序员通常不能正确地识别某些数据何时应该只有两个可能的值 指导程序员做什么的人,比如程序经理或编写程序员遵循的规范的人,通常也不能正确地识别这一点 即使一段数据被正确地识别为只有两种可能的状态,这种保证在将来也可能不成立。

在这些情况下,使用布尔变量会导致令人困惑的代码,这通常可以通过使用枚举来避免。

例子

假设一个程序员正在为一家只销售轿车和卡车的汽车经销商编写软件。程序员为他的软件开发一个全面的业务需求模型。由于知道所销售的车辆只有轿车和卡车两种类型,他正确地识别出可以在Vehicle类中使用一个布尔变量来指示车辆是轿车还是卡车。

class Vehicle {
 bool isTruck;
 ...
}

这个软件是这样写的,当isTruck为真时,车辆是一辆卡车,当isTruck为假时,车辆是一辆汽车。这是在整个代码中执行多次的简单检查。

一切都很顺利,直到有一天,汽车经销商收购了另一家同样销售摩托车的经销商。程序员必须更新软件,使其能够正确地考虑到经销商的业务发生了变化。现在它需要识别车辆是汽车、卡车还是摩托车,这是三种可能的状态。

程序员应该如何实现这一点?isTruck是一个布尔变量,所以它只能保存两种状态。他可以将其从布尔类型更改为允许多种状态的其他类型,但这将破坏现有的逻辑,并且可能无法向后兼容。从程序员的角度来看,最简单的解决方案是添加一个新变量来表示车辆是否是摩托车。

class Vehicle {
 bool isTruck;
 bool isMotorcycle;
 ...
}

代码更改后,当isTruck为真时,车辆为卡车,当isMotorcycle为真时,车辆为摩托车,当两者都为假时,车辆为汽车。

问题

这种解决方案存在两个大问题:

The programmer wants to express the type of the vehicle, which is one idea, but the solution uses two variables to do so. Someone unfamiliar with the code will have a harder time understanding the semantics of these variables than if the programmer had used just one variable that specifies the type entirely. Solving this motorcycle problem by adding a new boolean doesn't make it any easier for the programmer to deal with such situations that happen in the future. If the dealership starts selling buses, the programmer will have to repeat all these steps over again by adding yet another boolean.

软件的业务需求发生变化,要求他修改现有代码,这不是开发人员的错。但是首先使用布尔变量使得他的代码不那么灵活,也更难修改以满足未知的未来需求(不那么“适合未来”)。当他以最快的方式实现更改时,代码变得难以阅读。使用布尔变量最终是一个不成熟的优化。

解决方案

首先使用枚举就可以避免这些问题。

enum EVehicleType { Truck, Car }

class Vehicle {
 EVehicleType type;
 ...
}

为了在这种情况下容纳摩托车,程序员所要做的就是将Motorcycle添加到evhicletype中,并添加新的逻辑来处理摩托车的情况。不需要添加新的变量。现有的逻辑不应该被打乱。不熟悉代码的人也很容易理解车辆的类型是如何存储的。

悬崖笔记

不要使用只能存储两种不同状态的类型,除非您绝对确定两种状态总是足够的。如果将来可能需要两个以上的状态,则使用枚举,即使布尔值可以满足现有需求。

宏,预处理器指令和注释是邪恶的。

每个文件只使用一种语法和语言!

//不适用于Make文件或插入真实代码的编辑器宏。

低驼峰是愚蠢和没有语义的

使用lower camelCase使名称/标识符(从这里开始使用“name”)看起来像两个部分。然而,Upper CamelCase给出了清晰的指示,所有的单词都属于一起。

匈牙利符号是不同的…因为名称的第一部分是类型指示符,所以它与名称的其余部分具有单独的含义。

有些人可能会认为小写的驼峰大小写应该用于函数/过程,特别是在类内部。这在Java和面向对象的PHP中很流行。然而,没有理由这样做来表明它们是类方法,因为通过它们被访问的方式,很明显它们只是类方法。

一些代码示例:

# Java
myobj.objMethod() 
# doesn't the dot and parens indicate that objMethod is a method of myobj?

# PHP
$myobj->objMethod() 
# doesn't the pointer and parens indicate that objMethod is a method of myobj?

Upper CamelCase对于类名和其他静态名很有用。所有非静态内容都应该通过它们的访问方式来识别,而不是通过它们的名称格式(!)

这是我的同质代码示例,其中名称行为由其他事物表示,而不是它们的名称……(另外,我更喜欢用下划线来分隔名字中的单词)。

# Java
my_obj = new MyObj() # Clearly a class, since it's upper CamelCase
my_obj.obj_method() # Clearly a method, since it's executed
my_obj.obj_var # Clearly an attribute, since it's referenced

# PHP
$my_obj = new MyObj()
$my_obj->obj_method()
$my_obj->obj_var
MyObj::MyStaticMethod()

# Python
MyObj = MyClass # copies the reference of the class to a new name
my_obj = MyObj() # Clearly a class, being instantiated
my_obj.obj_method() # Clearly a method, since it's executed
my_obj.obj_var # clearly an attribute, since it's referenced
my_obj.obj_method # Also, an attribute, but holding the instance method.
my_method = myobj.obj_method # Instance method
my_method() # Same as myobj.obj_method()
MyClassMethod = MyObj.obj_method # Attribute holding the class method
MyClassMethod(myobj) # Same as myobj.obj_method()
MyClassMethod(MyObj) # Same as calling MyObj.obj_method() as a static classmethod

这就是我对camelCase完全客观的看法。

汇编程序没有死

在我的工作(复制保护系统)中,汇编程序是必不可少的,我使用了许多hll复制保护系统,只有汇编程序才能真正地利用隐藏在代码中的所有可能性(如代码突变,低级别的东西)。

此外,许多代码优化只有通过汇编程序才能实现,看看任何视频编解码器的源代码,源代码都是用汇编程序编写的,并优化为使用MMX/SSE/SSE2操作码,许多游戏引擎使用汇编程序优化例程,甚至Windows内核也有SSE优化例程:

NTDLL.RtlMoveMemory

.text:7C902CD8                 push    ebp
.text:7C902CD9                 mov     ebp, esp
.text:7C902CDB                 push    esi
.text:7C902CDC                 push    edi
.text:7C902CDD                 push    ebx
.text:7C902CDE                 mov     esi, [ebp+0Ch]
.text:7C902CE1                 mov     edi, [ebp+8]
.text:7C902CE4                 mov     ecx, [ebp+10h]
.text:7C902CE7                 mov     eax, [esi]
.text:7C902CE9                 cld
.text:7C902CEA                 mov     edx, ecx
.text:7C902CEC                 and     ecx, 3Fh
.text:7C902CEF                 shr     edx, 6
.text:7C902CF2                 jz      loc_7C902EF2
.text:7C902CF8                 dec     edx
.text:7C902CF9                 jz      loc_7C902E77
.text:7C902CFF                 prefetchnta byte ptr [esi-80h]
.text:7C902D03                 dec     edx
.text:7C902D04                 jz      loc_7C902E03
.text:7C902D0A                 prefetchnta byte ptr [esi-40h]
.text:7C902D0E                 dec     edx
.text:7C902D0F                 jz      short loc_7C902D8F
.text:7C902D11
.text:7C902D11 loc_7C902D11:                           ; CODE XREF: .text:7C902D8Dj
.text:7C902D11                 prefetchnta byte ptr [esi+100h]
.text:7C902D18                 mov     eax, [esi]
.text:7C902D1A                 mov     ebx, [esi+4]
.text:7C902D1D                 movnti  [edi], eax
.text:7C902D20                 movnti  [edi+4], ebx
.text:7C902D24                 mov     eax, [esi+8]
.text:7C902D27                 mov     ebx, [esi+0Ch]
.text:7C902D2A                 movnti  [edi+8], eax
.text:7C902D2E                 movnti  [edi+0Ch], ebx
.text:7C902D32                 mov     eax, [esi+10h]
.text:7C902D35                 mov     ebx, [esi+14h]
.text:7C902D38                 movnti  [edi+10h], eax

所以,如果你下次听到汇编器死了,想想你最近看过的电影或玩过的游戏(以及它的复制保护)。

编程:这是一份有趣的工作。

我似乎看到了两类开发人员。有些人不喜欢,但他们有能力,薪水也不错。另一组人喜欢它的程度有点令人毛骨悚然。这似乎就是他们的生活。

我只是觉得这份工作薪水高,而且有趣。每一天的每一分钟都有各种各样的学习新东西的空间。我想不出其他我更喜欢的工作了。但这仍然是一份工作。妥协是要做出来的,你生产的东西并不总是那么好。

因为我更愿意在沙滩上喝啤酒或和孩子们一起玩。