1.Conditional Expression
var CleanReply = function (request, reply)
{
//Here’s a case where the ternary operator is readable and compact:
time_str += (hour >= 12) ? "pm" : "am";
//Avoiding the ternary operator, you might write:
if (hour >= 12) {
time_str += "pm";
} else {
time_str += "am";
}
//these expressions can quickly become difficult to read:
exponent >= 0 ? mantissa * (1 << exponent) : mantissa / (1 << -exponent);
//Spelling out the logic with an if/else statement makes the code more natural:
if (exponent >= 0) {
return mantissa * (1 << exponent);
} else {
return mantissa / (1 << -exponent);
}
}
2.don’t” is drowned out by the more unusual
var CleanReply = function (request, reply)
{
if (!url.HasQueryParameter("expand_all")) {
response.Render(items);
} else {
for (var i = 0; i < items.size(); i++) {
items[i].Expand();
}
}
/* it’s the more interesting case (and it’s the
positive case, too), let’s deal with it first:*/
if (url.HasQueryParameter("expand_all")) {
for (var i = 0; i < items.size(); i++) {
items[i].Expand();
}
}else {
response.Render(items);
}
}
3.Removing Nesting Inside Loops
var Contains = function (request, reply)
{
/* here’s a case of code
nested in a loop:*/
for (var i = 0; i < results.size(); i++) {
if (results[i] != NULL) {
//non_null_count++
if (results[i].name != "") {
//cout << "Considering candidate..." << endl;
}
}
}
//Inside a loop, the analogous technique to returning early is to continue:
for (int i = 0; i < results.size(); i++) {
if (results[i] == NULL) continue
//non_null_count++;
if (results[i].name == "") continue;
//cout << "Considering candidate..." << endl;
}
}
4. Removing Nesting by Returning Early
var CleanReply = function (request, reply)
{
//if you notice yourself looking back up to doublecheck
//which block conditions you’re in:
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();
//Nesting like this can be removed by handling the “failure cases”
//as soon as possible and returning early from the function:
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();
}
5. Returning Early from a Function
//Returning early from a function is perfectly fine—and often desirable. For example:
var Contains = function (request, reply)
{
if (str == null || substr == null) return false;
if (substr.equals("")) return true;
}
cf) 반환 포인트를 하나만 두려는 건 함수의 끝부분에서 실행되는 cleanup 코드의 호출을 보장하려는 의도다.
하지만 현대의 언어는 클린업 코드를 실행시키는 더 정교한 방법을 제공한다. C# 의 Using / try finally
그러므로 여러 곳에서 반환하는 것도 바람직 할 수 있다.
6. 아래와 같은 구조가 차지하는 것이 많은 프로그램은 흐름을 쫒아가기 어려워질 수 있다. 이 비율이 너무 놓지 않아야한다.
쓰레딩 - 어느 코드가 언제 실행되는지 불분명
시그널/ 인터럽트 핸들러 - 어느 코드가 어떤 시점에 실행될지 모른다.
예외 - 예외 처리가 여러 함수 호출을 거치면서 실행될 수 있다.
함수 포인터 & 익명함수 - 실행할 함수가 런타임에 결정되기 때문에 컴파일 과정에서는 어떤코드가 실행될지 알기 어렵다.
가상 메소드 - object.virtualmethod() 알려지지 않은 하위클래스의 코드를 호출할지도 모른다.