在阅读" 你的/你的圈复杂度有什么限制? "之后,我意识到我的很多同事对我们项目的新QA政策非常恼火:每个功能不再有10个圈复杂度.
含义:不超过10'if','else','try','catch'和其他代码工作流程分支语句.对.正如我在' 你测试私人方法吗?',这样的政策有很多好的副作用.
但是:在我们(200人 - 7年)项目开始时,我们很高兴地记录(不,我们不能轻易地将其委托给某种' 面向方面编程 '的日志方法).
myLogger.info("A String");
myLogger.fine("A more complicated String");
...
Run Code Online (Sandbox Code Playgroud)
当我们的系统的第一个版本上线时,我们遇到了巨大的内存问题,不是因为日志记录(在某一点被关闭),而是因为日志参数(字符串),总是被计算,然后传递给'info()'或'fine()'函数,只是发现日志记录级别为"OFF",并且没有记录日志!
所以QA回来并敦促我们的程序员进行条件记录.总是.
if(myLogger.isLoggable(Level.INFO) { myLogger.info("A String");
if(myLogger.isLoggable(Level.FINE) { myLogger.fine("A more complicated String");
...
Run Code Online (Sandbox Code Playgroud)
但是现在,由于每个功能限制的"无法移动"10个圈复杂度级别,他们认为他们在其功能中放入的各种日志被视为负担,因为每个"if(isLoggable())"是计为+1圈复杂度!
因此,如果一个函数有8'if','else'等等,在一个紧密耦合的不易共享的算法中,以及3个关键的日志操作......它们违反了限制,即使条件日志可能不是真的该功能的复杂性的一部分......
你会如何解决这种情况?
我在项目中看到过几个有趣的编码演变(由于这个'冲突'),但我只是想先了解你的想法.
谢谢你的所有答案.
我必须坚持认为问题不是"格式化"相关,而是"参数评估"相关(评估可能非常昂贵,只是在调用一个什么都不做的方法之前)
所以当写一个上面的"A String"时,我实际上意味着机能缺失(),与机能缺失()返回一个字符串,并且是一个复杂的方法收集的调用和计算所有类型的日志数据被记录器...与否(因此该问题,并显示义务,以使用条件记录,因此人为增加'圈复杂度'的实际问题......)
我现在得到你们中某些人提出的" 可变函数"点(谢谢John).
注意:java6中的快速测试表明我的varargs函数在被调用之前会对其参数进行求值,所以它不能用于函数调用,而是用于'Log Retriever object'(或'function wrapper'),其中toString( )只有在需要时才会被调用.得到它了.
我现在已经发表了关于这个主题的经验.
我会留在那里直到下周二投票,然后我会选择你的一个答案.
再次,谢谢你的所有建议:)
language-agnostic logging coding-style cyclomatic-complexity
我用eclipse编程,有时使用像SciTE或vim这样的GUI文本编辑器.但是,我正处于一个项目中,需要我在80列SSH窗口中通过ssh连接编辑文件.
因为sudo vim在打开文件之前我必须(*颤抖*)我不知道如何在终端外的编辑器中打开文件(这样我就可以看到文本超过80列).如果命令行较大,那么我猜使用直接vim不会有问题.
我不知道如何处理这种情况以及如何将这个噩梦变成一个可管理的编码环境.
JShint和以下代码行有一些问题.
$location.path('map-' + map.id + '/venue-' + map.attributes.default_venue.value);
Run Code Online (Sandbox Code Playgroud)
我收到了错误,Identifier 'default_venue' is not in camel case.这通常不会成为问题,但我对变量名称没有任何控制权 - 它是通过JSON API引入的.
有没有办法可以为受影响的变量或它们出现的行抑制此问题?
如果之前有人问过这个道歉,我很确定它一定是,但我找不到解决办法.
列表推导在某些情况下可能很有用,但它们也可能相当可怕阅读..作为一个有点夸张的例子,你会如何缩进以下内容?
allUuids = [x.id for x in self.db.query(schema.allPostsUuid).execute(timeout = 20) if x.type == "post" and x.deleted is not False]
Run Code Online (Sandbox Code Playgroud) 我们是否应该有一个团队编码标准,抽象类的名称有前缀Abstract?例如
public abstract class AbstractB implements B {}
Run Code Online (Sandbox Code Playgroud) 我是一名相当新秀的C++程序员,但由于我对该语言的经验有限,大多数标准C++风格指南(例如Google C++样式指南)都与stl和boost库中实现的内容相悖.
例如,在C++标准库和升压类名称总是小写,用下划线分隔的话(例如std::vector,boost::unordered_map,std::map::const_iterator),而多数风格指南我已经看到了C++向驼峰样式(如倾向于TcpConnection或Int32).
这同样适用于方法.标准库和Boost使用与类(例如std::map<>::get_equal("foo"))相同的方法和函数样式,而大多数样式指南使用pascalCase或CamelCase.
如果我们将这与像Ruby这样的语言形成对比,大多数用户都会遵循核心库中使用的约定,那么标准C++库和其他人的代码之间会有这样的差异,这似乎很奇怪.
有人知道为什么吗?
编辑:只是为了澄清,我只是简单地谈论肤浅的文本风格(套管,使用下划线等)而不是实际的实现风格.
我发现了一种新的模式.这种模式是众所周知的还是对它的看法是什么?
基本上,我很难刷新源文件以找出可用的模块导入等等,所以现在,而不是
import foo
from bar.baz import quux
def myFunction():
foo.this.that(quux)
Run Code Online (Sandbox Code Playgroud)
我将所有导入移动到它们实际使用的函数中,如下所示:
def myFunction():
import foo
from bar.baz import quux
foo.this.that(quux)
Run Code Online (Sandbox Code Playgroud)
这做了一些事情.首先,我很少意外地用其他模块的内容污染我的模块.我可以__all__为模块设置变量,但随后我必须在模块发展时更新它,这对于实际存在于模块中的代码无效.
其次,我很少在我的模块顶部进行一连串的进口,其中一半或更多我不再需要,因为我已经重构了它.最后,我发现这个模式更容易阅读,因为每个引用的名称都在函数体中.
在C++中命名函数的惯例是什么?
我来自Java环境所以我通常命名为:
myFunction(...) {
}
Run Code Online (Sandbox Code Playgroud)
我在C++中看过混合代码,
myFunction(....)
MyFunction(....)
Myfunction(....)
Run Code Online (Sandbox Code Playgroud)
什么是正确的方法?
另外,对于类方法还是非类方法,它是一样的吗?
在编写python模块和函数时,我有一些应该暴露给外人的"公共"函数,但是其他一些"私有"函数只能在本地和内部看到和使用.
我理解在python中没有绝对的私有函数.但是,区分"公共"功能和"私人"功能的最佳,最整洁或最常用的风格是什么?
我列出了一些我所知道的风格:
__all__在模块文件中使用以指示其"公共"函数(python __all__模块级变量是什么?)人们使用其他任何想法或约定吗?
非常感谢你!
这可能是一个宗教论点,但在我的工作中一直争论是否所有IF语句都应该包含一个ELSE子句 - 即使ELSE子句只包含一条注释表明它是'故意留空'.
我听过双方的争论:'For'阵营 - 确保代码实际上已经解决了条件是否需要ELSE条款'反对'阵营 - 代码难以阅读,增加了太多的噪音
我对任何其他观点感兴趣,因为我必须以满足双方的答案来解决这场辩论.
谢谢您的帮助.
顺便说一句:我确实搜索了StackOverflow以获得答案,但却无法找到答案.如果有,只需包含一个链接并关闭.谢谢.
coding-style ×10
c++ ×2
python ×2
code-cleanup ×1
conventions ×1
editor ×1
function ×1
java ×1
javascript ×1
jshint ×1
logging ×1
naming ×1
python-2.7 ×1
ssh ×1
terminal ×1