1. 为什么审美这么重要?
让人愉悦的代码更易读,因此更容易使用。
2. 重新安排换行来保持一致和紧凑
下面的代码有着优雅一致的风格,并且很容易从头看到尾快速浏览。
但是缺憾在于用了更多的纵向空间,并且注释重复了三遍。
1 public class PerformanceTester { 2 public static final TcpConnectionSimulator wifi = 3 new TcpConnectionSimulator( 4 500, /* Kbps */ 5 80, /* millisecs latency */ 6 200, /* jitter */ 7 1 /* packet loss % */); 8 9 public static final TcpConnectionSimulator t3_fiber = 10 new TcpConnectionSimulator( 11 45000, /* Kbps */ 12 10, /* millisecs latency */ 13 0, /* jitter */ 14 0 /* packet loss % */); 15 16 public static final TcpConnectionSimulator cell = 17 new TcpConnectionSimulator( 18 100, /* Kbps */ 19 400, /* millisecs latency */ 20 250, /* jitter */ 21 5 /* packet loss % */); 22 }
更紧凑的书写方式如下:
1 public class PerformanceTester { 2 // TcpConnectionSimulator(throughput, latency, jitter, packet_loss) 3 // [Kbps] [ms] [ms] [percent] 4 public static final TcpConnectionSimulator wifi = 5 new TcpConnectionSimulator(500, 80, 200, 1); 6 public static final TcpConnectionSimulator t3_fiber = 7 new TcpConnectionSimulator(45000, 10, 0, 0); 8 public static final TcpConnectionSimulator cell = 9 new TcpConnectionSimulator(100, 400, 250, 5); 10 }
3. 用方法(函数)整理不规则的东西
下面这段代码没有什么美感可言。
1 DatabaseConnection database_connection; 2 string error; 3 assert(ExpandFullName(database_connection, "Doug Adams", &error) 4 == "Mr. Douglas Adams"); 5 assert(error == ""); 6 assert(ExpandFullName(database_connection, " Jake Brown ", &error) 7 == "Mr. Jacob Brown III"); 8 assert(error == ""); 9 assert(ExpandFullName(database_connection, "No Such Guy", &error) == ""); 10 assert(error == "no match found"); 11 assert(ExpandFullName(database_connection, "John", &error) == ""); 12 assert(error == "more than one result");
需要一个辅助函数来改进。
1 void CheckFullName(string partial_name, 2 string expected_full_name, 3 string expected_error) { 4 // database_connection is now a class member 5 string error; 6 string full_name = ExpandFullName(database_connection, partial_name, &error); 7 assert(error == expected_error); 8 assert(full_name == expected_full_name); 9 } 10 11 CheckFullName("Doug Adams", "Mr. Douglas Adams", ""); 12 CheckFullName(" Jake Brown ", "Mr. Jake Brown III", ""); 13 CheckFullName("No Such Guy", "", "no match found"); 14 CheckFullName("John", "", "more than one result");
尽管目的仅仅是让代码更有美感,但是还产生了几个附带的效果
(1)消除了代码中的重复,使之变得更紧凑
(2)每个测试用例重要的部分都变得更直白
(3)添加新的测试更加简单
4. 在需要时使用列对齐
对于上面的例子,可以使用列对齐。这样能使得错误更加明显,阅读时很容易从一列跳到另一列。
1 CheckFullName("Doug Adams" , "Mr. Douglas Adams" , ""); 2 CheckFullName(" Jake Brown ", "Mr. Jake Brown III", ""); 3 CheckFullName("No Such Guy" , "" , "no match found"); 4 CheckFullName("John" , "" , "more than one result");
1 commands[] = { 2 ... 3 { "timeout", NULL, cmd_spec_timeout }, 4 { "timestamping", &opt.timestamping, cmd_boolean }, 5 { "tries", &opt.ntry, cmd_number_inf }, 6 { "useproxy", &opt.use_proxy, cmd_boolean }, 7 { "useragent", NULL, cmd_spec_useragent }, 8 ... 9 };
有些人不喜欢列对齐,因为维护工作量大。实际可能不会有太大的工作量,不妨试试。
5. 把声明按块(逻辑)组织起来
1 class FrontendServer { 2 public: 3 FrontendServer(); 4 ~FrontendServer(); 5 6 // Handlers 7 void ViewProfile(HttpRequest* request); 8 void SaveProfile(HttpRequest* request); 9 void FindFriends(HttpRequest* request); 10 11 // Request/Reply Utilities 12 string ExtractQueryParam(HttpRequest* request, string param); 13 void ReplyOK(HttpRequest* request, string html); 14 void ReplyNotFound(HttpRequest* request, string error); 15 16 // Database Helpers 17 void OpenDatabase(string location, string user); 18 void CloseDatabase(string location); 19 };
6. 把代码分成段落,同时为段落加上总结性注释
1 def suggest_new_friends(user, email_password): 2 # Get the user's friends' email addresses. 3 friends = user.friends() 4 friend_emails = set(f.email for f in friends) 5 6 # Import all email addresses from this user's email account. 7 contacts = import_contacts(user.email, email_password) 8 contact_emails = set(c.email for c in contacts) 9 10 # Find matching users that they aren't already friends with. 11 non_friend_emails = contact_emails - friend_emails 12 suggested_friends = User.objects.select(email__in=non_friend_emails) 13 14 # Display these lists on the page. 15 display['user'] = user 16 display['friends'] = friends 17 display['suggested_friends'] = suggested_friends 18 return render("suggested_friends.html", display)
7. 个人风格与一致性
一致的风格比“正确”的风格更重要
1 class Logger { 2 //... 3 }; 4 5 class Logger 6 { 7 //... 8 };