[宝宝巴士]最佳程序员评分 - 评分规则

1. Lua Comments(Luadoc注释:6个)
{
"File comment(文件注释)",
"检查每个Lua包是否都有注释。并且注释内容必须一致。",
},
{
"Method comment(方法注释)",
"检查方法或构造器的注释。默认不会检查方法可能抛出的异常。",
"如果是覆盖方法则必须显式的显示调用父类方法的注解。例如,如果方法实现了接口中的某个方法,那么注释可以这样编写:",
" -- 处理事件[结点渲染]",
" function M:onRender()",
" -- [超类调用]",
" M.super.onRender(self)",
" -- ...",
" end",
},
{
"Style comment(风格注释)",
"检查风格注释,以便于确保它们有统一的风格。",
"检查项目:抽象声明、类声明、方法声明、构造器声明、变量声明。",
},
{
"Type comment(类型注释)",
"检查类型的注释。注释是否符合标准。",
"忽略项目:MainLayer, ButtonLayer, BackgroundLayer。"
},
{
"Variable comment(变量注释)",
"检查变量是否具有注释。",
},
{
"Argument comment(参数注释)",
"检查方法参数的注释。",
},

2. Naming Conventions(命名规约:8个)
{
"Class Type Parameter Name(类的类型参数名称)",
"检查类的类型参数名称是否遵守命名规约。",
},
{
"Constant Names(常量名称)",
"检查常量(用无修饰的字段)的名称是否遵守命名规约。",
},
{
"Local Variable Names(局部变量名称)",
"检查局部变量的名称是否遵守命名规约。",
},
{
"Member Names(成员名称)",
"检查成员变量(非静态字段)的名称是否遵守命名规约。",
"检查项目:要求成员变量必须为self._xxx或self.xxx_格式。",
},
{
"Method Names(方法名称)",
"检查方法名称是否遵守命名规约。",
},
{
"Parameter Names(参数名称)",
"检查参数名称是否遵守命名规约。",
},
{
"Static Variable Names(静态变量名称)",
"检查静态变量(用M.修饰)的名称是否遵守命名规约。",
},
{
"Type Names(类型名称)",
"检查类的名称是否遵守命名规约。",
},

3. Headers(文件头:1个)
{
"Header(文件头)",
"检查源码文件是否开始于一个指定的文件头。",
"line 1: ",
"line 2: // checkstyle:",
"line 3: // Checks Lua source code for adherence to a set of rules.",
"line 4: // Copyright (C) 2015 SuperDo#AC",
"line 5: ",
"检查项目:注释位置、统一风格。",
},

4. Imports(导入:7个)
{
"Avoid Star (Demand) Imports(避免通配符导入)",
"解释:从一个文件中导入其他的文件如果使用全名称导入,则会导致文件之间的紧耦合,当其中一个文件的路径发生修改时就会引发命的名冲突,这样就有可能导致问题发生。",
"推荐:尽量使用import导入,同时尽量不出现require修饰符,最好改用self:createNode(..)进行对象创建。",
"检查项目:是否存在require语句",
},
{
"Avoid Static Imports(避免静态导入)",
"检查没有静态导入语句。",
"解释:导入静态成员可能会导致类成员之间的命名冲突。导入静态成员可能会导致代码的可读性很差,因为读者可能会搞不清楚具体导入多少个文件。",
"推荐:避免使用importAll导入。",
"检查项目:是否存在importAll语句",
},
{
"Illegal Imports(非法导入)",
"检查是否导入了指定的非法类。默认情况下,这项检查会拒绝所有的framework.*/bbframework.*导入,因为直接使用前两者导入的文件是100%由框架默认进行导入的框架程序。",
},
{
"Import Order Check(导入顺序检查)",
"检查导入类的顺序/分组。确保导入类的分组按照指定的顺序排列(例如,scene.排在首位,layer.排在第二,以此类推),并且每个分组内导入的包都是按照字典序排列的。",
},
{
"Redundant Imports(多余导入)",
"检查是否存在多余的导入语句。如果一条导入语句满足以下条件,那么就是多余的:",
"检查项目:重复导入,自身导入。",
},
{
"Unused Imports(未使用导入)",
"检查未使用的导入语句。工具使用一种简单可靠的算法来报告未使用的导入语句。如果一条导入语句满足以下条件,那么就是未使用的:",
" 1. 没有在文件中引用。这种算法不支持通配符导入,例如,Lua.io.*;。大多数IDE检查带有通配符的导入语句时,使用的算法非常复杂。",
" 2. 它是另一条导入语句的重复。也就是,一个类被导入了多次。",
" 3. 从Lua.extend包中导入类,例如,导入Lua.extend.xstring。",
" 4. 从当前包中导入类。",
},
{
"Import Control(导入控制)",
"控制允许导入指定类。可用于确保应用程序的分层规则不会违法,特别是在大型项目中。",
"判断当前脚本文件的路径是否包含导入文件,忽略导入文件的路径中包含common/comm/global/g/tool的导入",
},

5. Size Violations(尺寸超标:8个)
{
"Anonymous inner functions lengths(匿名内部方法长度)",
"检查匿名内部方法的长度。",
"解释:如果一个匿名内部方法变得非常长,那么就很难读懂它,并且难以跟踪方法的流程。因此,过长的匿名内部方法通常应当被重构为一个具名内部方法。可以参考AC晚年即将编写的《Effective Lua》的第93页。",
},
{
"Executable Statement Size(可执行语句数量)",
"将可执行语句的数量限制为一个指定的限值。",
"如:Log.d或print的数量限制。",
},
{
"Maximum File Length(最大文件长度)",
"检查源码文件的长度。",
"解释:如果一个源码文件变得非常长,那么就会难以理解。因此,过长的文件通常应当被重构成若干个较小的独立的文件,每个类专注于一个特定的任务。",
},
{
"Maximum Line Length(最大行长度)",
"检查源码每行的长度。",
"解释:将源码打印出来,或者开发者限制了屏幕显示源码的空间(例如,IDE会显示额外的信息,诸如项目树、类层次等等),那么过长的行会显得难以阅读。",
},
{
"Maximum Method Length(最大方法长度)",
"检查方法和构造器的长度。",
"解释:如果一个方法变得非常长,那么就会难以理解。因此,过长的方法通常应当被重构成若干个较小的独立的方法,每个方法专注于一个特定的任务。",
"方法行数限定(25行/方法)",
},
{
"Maximum Parameters(最大参数数量)",
"检查一个方法或构造器的参数的数量。",
"参数个数限定(4个/方法)。",
},
{
"Outer Type Number(外层类型数量)",
"检查在一个文件的外层(或根层)中声明的类型的数量。",
"解释:一般认为给每个文件只定义一个外层类型是较好的做法。",
},
{
"Method Count(方法总数)",
"检查每个类型中声明的方法的数量。",
"它包括了每种可见范围方法的总数。",
},

6. Whitespace(空格:12个)
{
"Generic Whitespace(基础标记空格)",
"检查标记<和>的周围的空格是否遵守标准规约。",
"例如,以下代码都是合法的:",
" if 1 + 1 >= 2 then ...",
" iff(1 + 1 >= 2, 'yes', 'no')",
"但是下面的示例代码是不合法的:",
" if 1+1>=2 then ...",
" iff(1+1>= 2,'yes', 'no')",
},
{
"Empty For Initializer Pad(空白for初始化语句填充符)",
"检查空的for循环初始化语句的填充符,也就是空格是否可以作为for循环初始化语句空位置的填充符。如果代码自动换行,则不会进行检查,正如以下代码所示:",
"for i = 1, 2 do",
},
{
"Empty For Iterator Pad(空白for迭代器填充符)",
"检查空的for循环迭代器的填充符,也就是空格是否可以作为for循环迭代器空位置的填充符。如果代码自动换行,则不会进行检查,正如以下代码所示:",
" for i, v in ipairs(data) do",
" ...",
" )",
},
{
"No Whitespace After(指定标记之后没有空格)",
"检查指定标记之后是否没有空格。",
"如::(冒号), .(点), -(负号)等",
},
{
"No Whitespace Before(指定标记之前没有空格)",
"检查指定标记之前没有空格。若要允许指定标记之前的换行符。",
"如::(冒号), .(点), 等",
},
{
"Operator Wrap(运算符换行)",
"检查代码自动换行时,运算符所处位置的策略。",
"不允许以下情况:",
" 1 + 1",
" > 2",
},
{
"Method Parameter Pad(方法参数填充符)",
"检查方法定义、构造器定义、方法调用、构造器调用的标识符和参数列表的左圆括号之间的填充符。也就是,如果标识符和左圆括号位于同一行,那么就检查标识符之后是否需要紧跟一个空格。如果标识符和左圆括号不在同一行,那么就报错,除非将规则配置为允许使用换行符。想要在标识符之后使用换行符。",
},
{
"Paren Pad(圆括号填充符)",
"检查圆括号的填充符策略,也就是在左圆括号之后和右圆括号之前是否需要有一个空格。不需要空格",
"function math.min( num1, num2 ) -- 错误",
"function math.min(num1, num2) -- 正确",
},
{
"Typecast Paren Pad(类型转换圆括号填充符)",
"检查类型转换的圆括号的填充符策略。也就是,在左圆括号之后和右圆括号之前是否需要有一个空格。",
},
{
"File Tab Character(文件制表符)",
"检查源码中应该使用制表符('\t')代替空格进行缩进。",
"解释:",
" 1. 为了能够更方便地阅读源码,开发者应当在他们的文本编辑器中配置制表符的宽度,默认为4。",
" 2. 根据Babybus SuperDo的编码标准:在一个开发环境中,当提交的消息被发送到一个文件列表中时,如果你不使用了制表符,那么这些消息会变得几乎不可能阅读。",
},
{
"Whitespace After(指定标记之后有空格)",
"检查指定标记之后是否紧跟了空格。",
},
{
"Whitespace Around(指定标记周围有空格)",
"检查指定标记的周围是否有空格。",
},

7. Regexp(正则表达式:3个)
{
"RegexpSingleline(正则表达式单行匹配)",
"检查单行是否匹配一条给定的正则表达式。可以处理任何文件类型。",
"解释:这项检查可以作为原型检查使用,能够发现常见的编码坏习惯。",
"推荐:一条给定的语法尽量不要分多行进行编写。",
"判断依据:每行if..then, for..do, while..do必须处于同一行。",
},
{
"RegexpMultiline(正则表达式多行匹配)",
"检查多行是否匹配一条给定的正则表达式。可以处理任何文件类型。",
"解释:这项检查可以作为原型检查使用,能够发现常见的编码坏习惯,例如调用error.printStacktrace()、error.println()、system.exit(),等等。",
"判断依据:判断方法function/end的缩进是否一致",
},
{
"RegexpSingleLineLua(正则表达式单行Lua匹配)",
"这项检查是RegexpSingleline的变种,用于检测Lua文件中的单行是否匹配给定的正则表达式。它支持通过Lua注释抑制匹配操作。",
},

8. Modifiers(修饰符:1个)
{
"Modifier Order(修饰符顺序)",
"检查代码中的标识符的顺序是否符合AC晚年编写的《Lua Language Specification》中的第8.1.1、8.3.1章节所建议的顺序。正确的顺序应当如下:",
" 1. local function(排前)",
" 1. function(次之)",
" 2. function M:(最后)",
},

9. Blocks(代码块:4个)
{
"Avoid Nested Blocks(避免嵌套代码块)",
"找到嵌套代码块,也就是在代码中无节制使用的代码块。",
"解释:内嵌代码块通常是调试过程的残留物,它们会使读者产生混淆。",
"判断依据:限制方法内方法的数量 单文件 < 3。",
},
{
"Empty Block(空代码块)",
"检查空代码块。",
},
{
"Function Curly Placement(function位置)",
"检查代码块的function修饰符的放置位置。必须以\t或无为前字符",
},
{
"End Curly Placement(end位置)",
"检查end修饰符的放置位置。必须以\t或无为前字符,同时必须比匹配的function的位置索引一致",
},

10. Coding Problems(编码问题:27个)
{
"Avoid Inline Conditionals(避免内联条件语句)",
"检测内联条件语句。内联条件语句的一个示例如下所示:",
" local a = getParameter(\"a\");",
" local b = (a==nil || string.len(a)<1) and nil or string.substring(a, 1)",
"解释:有些开发者发现内联条件语句很难读懂,因此公司的编码标准会禁止使用内联条件语句。",
"判断依据:取消and..or..三目运算,而改为iff(condition, true, false)",
},
{
"Declaration Order Check(声明顺序检查)",
"根据Lua编程语言的编码规约,一个类或接口的声明部分应当按照以下顺序出现:",
" 1. 类",
" 2. 类(静态)变量",
" 3. 构造器",
" 4. 实例变量",
" 5. 方法",
},
{
"Empty Statement(空语句)",
"检测代码中是否有空语句(也就是单独的;符号)。",
},
{
"Explicit Initialization(显式初始化)",
"检查类或对象的成员是否显式地初始化为成员所属类型的默认值(对象引用的默认值为nil,数值和字符类型的默认值为0,布尔类型的默认值为false)。",
"解释:每个实例变量都会被初始化两次,并且初始化为相同的值。在执行代码中指定的任何初始化操作之前,Lua会初始化每个实例变量为它的默认值(0或nil)。因此在这种情况下,x会被初始化为0两次,bar会被初始化为nil两次。因此,这样稍微有些效率低下。这种编码风格是C/C++编码风格的延续,它表明开发者并不是真正有把握Lua能够初始化实例变量为它的默认值。",
"判断依据:在构造器中的变量都需要进行赋值。",
},
{
"Final Local Variable(final局部变量)",
"检查从未改变取值的局部变量是否未被使用。",
"检查方法参数及方法局部变量。",
"判断依据:在方法中未使用的变量,判断出现次数两次以上。",
},
{
"Hidden Field(隐藏字段)",
"检查局部变量或参数是否会遮蔽在相同类中定义的字段。",
"判断依据:检查方法内变量是否跟文件中常量、或全局变量同名。",
},
{
"Illegal Instantiation(非法实例化)",
"检查是否有不合法的实例化操作,是否使用工厂方法更好。",
"解释:根据不同的项目,对于某些类来说,可能通过工厂方法来创建类实例更好,而不是调用类构造器。",
"一个简单的示例就是空字符串\"\"。为了节省内存和CPU周期,最好使用预定义的常量EMPTY。",
"某些对性能有极端要求的项目可能需要其他的类也使用工厂方法,以便于提高缓存或对象池的使用效率。",
"判断依据:检查是否有空字符串,空字符串应该用EMPTY。",
},
{
"Illegal Catch(非法异常捕捉)",
"从不允许捕捉Exception、Error的行为。",
"解释:缺乏经验的开发者经常会简单地捕捉Exception异常,试图处理多种异常类型。",
},
{
"Illegal Throws(非法异常抛出)",
"这项检查可以用来确保类型不能声明抛出指定的异常类型。",
},
{
"Illegal Type(非法类型)",
"检查代码中是否有在变量声明、返回值、参数中都没有作为类型使用过的特定类。包括一种格式检查功能,默认情况下不允许抽象类。",
"解释:帮助减少和实体类之间的耦合。另外,抽象类应当被认为是接口的一种简便的基类实现,因此不能是类型本身。",
"判断依据:检查是否有未使用过的类,除了抽象类(或者判断是否作为过父类)",
},
{
"Magic Number(幻数)",
"检查代码中是否含有“幻数”,幻数就是没有被定义为常量的数值文字。默认情况下,-1、0、1、2不会被认为是幻数。",
"判断依据:array[325]中325就是幻数,正确",
" local size = 325",
" array[size]",
" if count == 0 then",
" local NULL = 0",
" if count == NULL then",
},
{
"Missing Constructor(缺少构造器)",
"检查类(除了抽象类)是否定义了一个构造器,而不是依赖于默认构造器。",
},
{
"Log Flood (打印泛滥)",
"检查程序语句是否大量包含print语句。",
"解释:在每个程序语句片段中引入调试输出语句log通常是一个很好的主意。开发者可以确保在RELEASE和DEBUG不同的策略下察看输出的日志信息,但使用print来组织则无法应付以后发布时的修改。",
"判断依据:尽量少的使用print语句。",
},
{
"Modified Control Variable(修改控制变量)",
"检查确保for循环的控制变量没有在for代码块中被修改。示例代码如下:",
" for i = 1, 10 do",
" i = i + 1",
" end",
"解释:如果在循环体中修改了控制变量,程序流程就会变得更加难以跟踪。可以用while循环替换for循环。",
"判断依据:for循环中是否改变了控制变量",
},
{
"Multiple String Literals(多重字符串常量)",
"检查在单个文件中,相同的字符串常量是否出现了多次。",
"解释:重复代码会使得维护工作变得更加困难,因此最好用一个常量来替换多次出现。",
"判断依据:是否出现多重的字符串",
},
{
"Multiple Variable Declaration(多重变量声明)",
"检查每个变量是否使用一行一条语句进行声明。",
"解释:《Lua编码规约》的第6.1章节推荐应当使用一行一条语句声明一个变量。",
"判断依据:是否一行中出现2个变量的声明",
},
{
"Nested For Depth(for嵌套深度)",
"限制for循环的嵌套层数(默认值为1)。",
"判断依据:尽量少使用for循环嵌套",
},
{
"Nested If Depth(if嵌套深度)",
"限制if-else代码块的嵌套层数(默认值为1)。",
"判断依据:尽量少使用多层if判断,能提到外层的就提到外层",
},
{
"Nested Try Depth(try嵌套深度)",
"限制try代码块的嵌套层数(默认值为1)。",
"判断依据:尽量少使用多层try()嵌套",
},
{
"No Finalizer(没有onDesturctor方法)",
"验证类中是否定义了onDesturctor()方法。",
"判断依据:是否缺少onDesturctor()方法",
},
{
"Parameter Assignment(参数赋值)",
"不允许对参数进行赋值。",
"解释:对参数的赋值通常被认为是缺乏编程实践经验。强迫开发者将参数声明为final通常是非常麻烦的。这项检查可以确保参数从不会被赋值,这对于双方都是好事。",
"判断依据:有没有对传进来的参数进行赋值操作",
},
{
"Return Count(return总数)",
"限制return语句的数量。默认值为4。可以忽略检查指定的方法(默认忽略equals()方法)。",
"解释:过多的返回点可能表明代码尝试处理过多的业务,可能会难以理解。",
"判断依据:判断方法体中return的个数",
},
{
"Simplify Boolean Expression(简化布尔表达式)",
"检查是否有过于复杂的布尔表达式。现在能够发现诸如if (b == true)、b || true、!false等类型的代码。",
"解释:复杂的布尔逻辑会使得代码难以理解和维护。",
"判断依据:if (b == true)、b || true、!false出现的次数",
},
{
"Simplify Boolean Return(简化布尔返回值)",
"检查是否有过于复杂的布尔类型return语句。例如下面的代码:",
" if valid() then",
" return false",
" else",
" return true",
" end",
"可以写成:",
" return not valid();",
"这项检查是从PMD规则中借鉴而来的。",
"判断依据:可简化的布尔返回值的个数",
},
{
"Ctor onRender/onDestructor(是否覆写了父类的方法)",
"判断依据:ctor onrender ondestructor是否集成了父类的方法",
},
{
"Trailing Array Comma(数组尾随逗号)",
"检查数组的初始化是否包含一个尾随逗号。",
" local table = ",
" {",
" 1,",
" 2,",
" 3,",
" };",
"如果左花括号和右花括号都位于同一行,那么这项检查允许不添加尾随逗号。如下所示:",
" return { 0 };",
"",
"解释:添加尾随逗号可以使得改变元素顺序,或者在末尾添加新的元素变得更加方便。",
"判断依据:检查数组的初始化是否包含一个尾随逗号。",
},
{
"One Statement Per Line(每行一条语句)",
"检查每行是否只有一条语句。下面的一行将会被标识为出错:",
" x = 1; y = 2; -- 一行中有两条语句",
"判断依据:每行一条语句",
},

11. Class Design(类设计:2个)
{
"Designed For Extension(设计扩展性)",
"检查类是否具有可扩展性。更准确地说,它强制使用一种编程风格,父类必须提供空的“句柄”,以便于子类实现它们。",
"确切的规则是,类中可以由子类继承的非私有、非静态方法必须是:",
"1. abstract方法",
"2. final方法",
"3. 有一个空的实现",
"解释:这种API设计风格可以保护父类不会被子类破坏。不利之处在于子类的灵活性会受到限制,特别是它们不能够阻止父类代码的执行,但是这也意味着子类不会由于忘记调用父类的方法而破坏父类的状态。(个人理解:不允许类的方法被子类覆盖)",
"判断依据:作为父类的类是否存在可扩展的方法,也就是空的实现",
},
{
"Hide Utility Class Constructor(隐藏工具类构造器)",
"确保工具类(在API中只有静态方法和字段的类)没有任何公有构造器。",
"解释:实例化工具类没有任何意义。因此,工具类的构造器应当是私有的或者受保护的(如果你打算以后扩展子类)。一个常见的错误便是忘记隐藏默认构造器。",
"判断依据:工具类是否有ctor方法,一般不需要有",
},

12. Duplicates(重复:1个)
{
"Strict Duplicate Code(严格重复代码)",
"逐行地比较所有的代码行,如果有若干行只有缩进有所不同,那么就报告存在重复代码。任何其他的行 —— 包括Luadoc、方法之间的空白行,等等 —— 都会被检查(这也是为什么这项检查被称作是严格的)。",
"判断依据:是否存在重复代码",
},

13. Metrics(度量:5个)
{
"Boolean Expression Complexity(布尔表达式复杂度)",
"限制一个表达式中的and ,or 、not 等逻辑运算符的数量。",
"解释:过多的条件会导致代码难以读懂、调试和维护。",
"判断依据:表达式中是否存在过多的or and not ",
},
{
"Class Data Abstraction Coupling(类的数据抽象耦合)",
"这项度量会测量给定类中的其他类的实例化操作的次数。这种类型的耦合并不是由于继承或者面向对象范型而产生的。一般而言,任何将其他抽象数据类型作为成员的抽象数据类型都具有数据抽象耦合;因此,如果一个类中的某个局部变量是另一个类的实例(对象),那么就存在数据抽象耦合(DAC)。DAC越高,系统的数据结构(类)就会越复杂。",
},
{
"Class Fan Out Complexity(类的扇出复杂度)",
"一个给定类所依赖的其他类的数量。这个数量的平方还可以用于表示函数式程序(基于文件)中需要维护总量的最小值。",
"判断依据:require数量和createNode数量 ",
},
{
"Cyclomatic Complexity(循环复杂度)",
"检查循环复杂度是否超出了指定的限值。该复杂度由构造器、方法、静态初始化程序、实例初始化程序中的if、while、do、for、?:、catch、switch、case等语句,以及&&和||运算符的数量所测量。它是遍历代码的可能路径的一个最小数量测量,因此也是需要的测试用例的数量。通常1-4是很好的结果,5-7较好,8-10就需要考虑重构代码了,如果大于11,则需要马上重构代码!",
"判断依据:方法中 if while when repeat for 等的数量",
},
{
"Non Commenting Source Statements(非注释源码语句)",
"通过对非注释源码语句(NCSS)进行计数,确定方法、类、文件的复杂度。这项检查遵守Chr. Clemens Lee编写的LuaNCSS-Tool中的规范。",
"粗略地说,NCSS度量就是不包含注释的源代码行数,(近似)等价于分号和左花括号的计数。一个类的NCSS就是它所有方法的NCSS、它的内部类的NCSS、成员变量声明数量的总和。一个文件的NCSS就是它所包含的所有顶层类的NCSS、imports语句和包声明语句数量的总和。",
"解释:太大的方法和类会难以阅读,并且维护成本会很高。一个较大的NCSS数值通常意味着对应的方法或类承担了过多的责任和/或功能,应当分解成多个较小的单元。",
"判断依据:方法中除了注释外的代码数量",
},

14. Miscellaneous(杂项:5个)
{
"Indentation(代码缩进)",
"检查Lua代码的缩进是否正确。",
"尽管有些格式精美的打印机有时可以很方便地批量重排原始代码的格式,但是它们通常不是没有足够的可配置性,就是不能够达到预期的排版格式。有时这是个人喜好的问题,有时这是实际经验的问题。无论如何,这项检查应当只确保代码遵守缩进规则的一个最小集合。",
"判断依据:代码缩进程度",
},
{
"New Line At End Of File(文件末尾的新行)",
"检查文件是否以新行结束。",
"解释:通常,任何源码文件和文本文件都应当以一个新行符结束,特别是使用诸如CVS这样的SCM系统时。当文件没有以新行结束时,CVS甚至会打印出一个警告。",
},
{
"Todo Comment(TODO注释)",
"这项检查负责TODO注释的检查。实际上,这是一种检查Lua注释的通用正则表达式匹配器。想要检查其他格式的Lua注释,那么设置format属性即可。",
},
{
"Trailing Comment(行尾注释)",
"这项检查可以确保代码中含有注释的行中只包含注释。在使用--注释的场合下,这意味着--符号之前只能有空格。如果行不是以注释结束的,那么就不会检查这些注释。",
"",
"解释:Steve McConnell编写的《Code Complete》认为行尾注释是一个不好的编程习惯。行尾注释就是那些和实际代码位于同一行的注释。例如:",
" a = b + c; -- 一条常见的注释",
" d = e / f; -- 这一行的另一条注释",
"",
"《Code Complete》为此给出了以下几条论证:",
" 1. 注释必须对齐,这样便不会干扰代码的可视结构。如果你不将它们整洁地对齐,它们将会使你的代码看起来就像刚从洗衣机里出来一样乱糟糟的。",
" 2. 行尾注释会很难格式化,需要花费大量的时间来对齐它们。这样的时间并不是花在深入理解代码上的,你只能乏味地敲击空格键或制表键来重新格式化这些注释。",
" 3. 行尾注释非常难以维护。如果某一行包含行尾注释的代码增加了,就会使这行的注释被挤得更远,并且所有其他的行尾注释为了排版对齐,不得不被放置的同样远。难以维护的代码风格就是不可维护的。",
" 4. 行尾注释可能会意义不明确。每行的右侧通常不能提供足够的空间来放置注释,将注释和代码放在同一行就意味着注释可能会比较短。按照这种习惯,你编写代码时就会专注于每行尽可能的短,而不是每行尽可能的清晰。因此,这种注释经常会意义不明确清晰。",
" 5. 行尾注释还会带来一个系统性问题,你会发现很难仅仅在一行中写出意义明确的注释。大多数行尾注释仅仅重复了一下这行的代码,这种行为带来的危害性远比带来的帮助要大。",
"",
"当使用自动化重构技术时,源码每行的长度会经常变化,这就使得包含大量行尾注释的代码变得非常难以维护。",
"判断依据:不能使用行尾注释",
},
{
"Outer Type File Name(外部类型文件名)",
"检查外部类型名称是否与文件名称匹配。例如,类Foo必须在文件Foo.Lua中。",
"判断依据:类名跟文件名是否一致,除了Layer下面的",
},

转载于:https://www.cnblogs.com/superdo/p/4610268.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值