闽公网安备 35020302035485号
if (clubs[i].members[j] == users[k]) => (clubs[ci].members[mi] == users[ui]
这样更不容易取错值。
delay → delay_secs password → plaintext_password5.匈牙利命名法(PS.现在不多见了)
8.不同命名形式代表不同的变量“类别”,例如 const 全大写,类用帕斯卡,普通变量用驼峰
limit 是否包含边界值容易引起误解,建议使用 max,同理还有 min
.特定语言有特定含义的的方法需要注意,如 get()、size()
// 外形不同
public class PerformanceTester {
public static final TcpConnectionSimulator wifi = new TcpConnectionSimulator(
500, /* Kbps */
80, /* millisecs latency */
200, /* jitter */
1 /* packet loss % */);
public static final TcpConnectionSimulator t3_fiber =
new TcpConnectionSimulator(
45000, /* Kbps */
10, /* millisecs latency */
0, /* jitter */
0 /* packet loss % */);
public static final TcpConnectionSimulator cell = new TcpConnectionSimulator(
100, /* Kbps */
400, /* millisecs latency */
250, /* jitter */
5 /* packet loss % */);
}
// 外形相同
public class PerformanceTester {
public static final TcpConnectionSimulator wifi =
new TcpConnectionSimulator(
500, /* Kbps */
80, /* millisecs latency */
200, /* jitter */
1 /* packet loss % */);
public static final TcpConnectionSimulator t3_fiber =
new TcpConnectionSimulator(
45000, /* Kbps */
10, /* millisecs latency */
0, /* jitter */
0 /* packet loss % */);
public static final TcpConnectionSimulator cell =
new TcpConnectionSimulator(
100, /* Kbps */
400, /* millisecs latency */
250, /* jitter */
5 /* packet loss % */);
}
// 堆代码 duidaima.com
// 另一种注释方法
public class PerformanceTester {
// TcpConnectionSimulator(throughput, latency, jitter, packet_loss)
// [Kbps] [ms] [ms] [percent]
public static final TcpConnectionSimulator wifi =
new TcpConnectionSimulator(500, 80, 200, 1);
public static final TcpConnectionSimulator t3_fiber =
new TcpConnectionSimulator(45000, 10, 0, 0);
public static final TcpConnectionSimulator cell =
new TcpConnectionSimulator(100, 400, 250, 5);
}
.保持固定的顺序(PS. Vue 的官方 option 顺序)# remove everything after the second '*'
name = '*'.join(line.split('*')[:2])
不要为了注释而注释:// Find the Node in the given subtree, with the given name, using the given depth. Node* FindNodeInSubtree(Node* subtree, string name, int depth);尝试写添加实现细节:
// Find a Node with the given 'name' or return NULL. // If depth <= 0, only 'subtree' is inspected. // If depth == N, only 'subtree' and N levels below are inspected. Node* FindNodeInSubtree(Node* subtree, string name, int depth);PS.go 语言就是强迫你为 export 的函数写注释,千万不要为了写而写呀,可以参考下标准库的注释:https://golang.org/pkg/#stdlib
// Surprisingly, a binary tree was 40% faster than a hash table for this data. // The cost of computing a hash was more than the left/right comparisons.有些地方看似可以优化,但是自己已经实践得出并不能优化的结论,那就加上注释避免别人浪费时间。
// TODO(dustin): handle other image formats besides JPEG还有这些类型:
TODO: Stuff I haven’t gotten around to yet FIXME: Known-broken code here HACK: Admittedly inelegant solution to a problem XXX: Danger! major problem here这些注释同样应该遵循统一风格,这样全局搜索就能轻易找到不同类型的问题。
// Impose a reasonable limit - no human can read that much anyway. const int MAX_RSS_SUBSCRIPTIONS = 1000;想象读者需要知道什么
.用回车和注释将代码划分成块(PS.与代码美学讲的重复了)
// This class contains a number of members that store the same information as in the // database, but are stored here for speed. When this class is read from later, those // members are checked first to see if they exist, and if so are returned; otherwise the // database is read from and that data stored in those fields for next time. // 其实就是 ↓ // This class acts as a caching layer to the database.简化逻辑
while (bytes_received < bytes_expected)作者推荐把变量放在左边,这样比较符合人类语言习惯,例如:接受长度小于某个特定的值,而不是某个特定的值大于等于接受长度。
exponent >= 0 ? mantissa * (1 << exponent) : mantissa / (1 << -exponent)就不要用三元运算。
public boolean Contains(String str, String substr) {
if (str == null || substr == null) return false;
if (substr.equals("")) return true;
// ...
}
最小化嵌套if (user_result == SUCCESS) {
if (permission_result != SUCCESS) {
reply.WriteErrors('error reading permissions')
reply.Done()
return
}
reply.WriteErrors('')
} else {
reply.WriteErrors(user_result)
}
reply.Done()
上面的代码很可能是分两次编写的,最初的需求只有判断 user_result,后来新增需求判断 permission_result。其实这样的写法并不好理解,在处理新需求时,你可以尝试不要跟随以前的思路,从新的角度思考 if 条件怎么写:if (user_result != SUCCESS) {
reply.WriteErrors(user_result)
reply.Done()
return
}
if (permission_result != SUCCESS) {
reply.WriteErrors(permission_result)
reply.Done()
return
}
reply.WriteErrors('')
reply.Done()
德摩根定律 !(a||b) 等于 !a&&!b,!(a&&b) 等于 !a||!b
var remove_one = function(array, value_to_remove) {
var index_to_remove = null
for (var i = 0; i < array.length; i += 1) {
if (array[i] === value_to_remove) {
index_to_remove = i
break
}
}
if (index_to_remove !== null) {
array.splice(index_to_remove, 1)
}
}
缩减作用域class LargeClass {
string str_;
void Method1() {
str_ = ...;
Method2();
}
void Method2() {
// Uses str_
}
// Lots of other methods that don't use str_ ...
};
把 str_ 提取到被需要的最小范围:class LargeClass {
void Method1() {
string str = ...;
Method2(str);
}
void Method2(string str) {
// Uses str
}
// Now other methods can't see str.
};
另外还提到了 C 的 if 作用域和 JavaScript 的 IIFE,都是控制作用域范围的方法。var vote_changed = function(old_vote, new_vote) {
var score = get_score()
if (new_vote !== old_vote) {
if (new_vote === 'Up') {
score += old_vote === 'Down' ? 2 : 1
} else if (new_vote === 'Down') {
score -= old_vote === 'Up' ? 2 : 1
} else if (new_vote === '') {
score += old_vote === 'Up' ? -1 : 1
}
}
set_score(score)
}
但是如果不根据前后状态直接混在一起处理可以吗?可以,这就是所谓“每次做一件事”。我们把单个操作的变化抽离成函数,然后先减去旧的状态,再加上新的状态:var vote_value = function(vote) {
if (vote === 'Up') {
return +1
}
if (vote === 'Down') {
return -1
}
return 0
}
var vote_changed = function(old_vote, new_vote) {
var score = get_score()
score -= vote_value(old_vote) // remove the old vote
score += vote_value(new_vote) // add the new vote
set_score(score)
}
想法化为代码$is_admin = is_admin_request();
if ($document) {
if (!$is_admin && ($document['username'] != $_SESSION['username'])) {
return not_authorized();
}
} else {
if (!$is_admin) {
return not_authorized();
}
}
相信看了上面优化逻辑的话应该不会写出这样的代码了,在这章作者再解释了一次怎么修改这种代码:if (is_admin_request()) {
// authorized
} elseif ($document && ($document['username'] == $_SESSION['username'])) {
// authorized
} else {
return not_authorized();
}
// continue rendering the page ...
如果你发现很难描述你的问题或者代码……那可能你的代码逻辑存在一些问题,那更好了,再深度思考一下业务逻辑会不会有什么不对的地方吧。这事情做起来和 rubber ducking(也就是“小黄鸭调试法”)差不多,不难做到,却十分有效,十分推荐大家尝试。