chapter7-8



chapter7-8

0 0


chapter7-8


On Github scottxxx666 / chapter7-8

##Chapter7 ##提高控制流程可讀性 ###重要概念 讓所有的條件判斷、迴圈與其他改變流程的敘述"盡量自然" --用不需要使用者停下來重讀的方式撰寫程式碼 ###條件式中的流程順序(1/2)
							if (length >= 10)
					
							if (10 <= length)
					
###條件式中的流程順序(2/2)
							while (byte_received < byte_expected)
					
							while (byte_expected > byte_received)
					
左側|右側 ------------- | -------------- 代表比較對象|代表比較基準 數值較有變化|數值大多是固定常數 ###尤達表示法 為了避免
						if ($obj = null)
					
所以改成
						if (null == $obj)
					
_現代編譯器都會產生警告?_ ###if/else區塊順序 * 先處理肯定條件 * 先處理簡單的情況 * 先處理比較有趣或明顯的情況 ###要你不要想"粉紅色大象"!
						if (uri.HasQueryParameter("expand_all") != true) {
							response.Render(items);
						} else {
							for (int i = 0; i < item.size() ; i++) {
								item[i].Expand();
							}
						}
					
### 先處理簡單的情況
						if (!is_login) {
							// not login
						}
						else {
							// do  something
						}
					
###避免 do/while 迴圈
						// 從 node 開始搜尋,尋找指定的 name
						// 不考慮大於 max_length 之後的節點
						public boolean ListHasNode(Node node, String name, int max_length) {
							do {
								if (node.name().equals(name))
									return true;
								node = node.next();
							} while (node != null && --max_length > 0);
							
							return false;
						}
					
###為了避免 do/while
						body
						
						while (condition) {
							body again
						}
					
蠢 ###多數 do/while 可以改成 while
						public boolean ListHasNode(Node node, String name, int max_length) {
							while (node != null && max_length-- > 0) {
								if (node.name().equals(name))	return true;
								node = node.next();
							}
							return false;
						}
					
###避免在 do/while 裡面用 continue
						do {
							continue;
						} while (false);
					
###儘早由函數中返回
						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();
					
###用儘早返回函數消除巢狀結構
						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();
					
###消除迴圈中的巢狀結構
						for (int i=0; i < result.size();i++) {
							if(result[i] != NULL) {
								non_null_count++;
								if (result[i]->name != "") {
									cout << "Considering candidate.."<;>
###用continue去解
						for (int i=0; i < result.size();i++) {
							if(result[i] == NULL) continue;
							non_null_count++;
							
							if (result[i]->name == "") continue;
							cout << "Considering candidate.."<;>
###Chapter 7 結語 * 比較時,最好將會變動的數直放左側,固定不變得放右側 * if/else順序: 先處理肯定/容易/有趣 * 盡可能減少巢狀結構 ##Chapter 8 ##分解巨大表示式 ###解釋性變數 (explaining variable)
						if (line.split(':')[0].strip() == "root")
						
						
						
						user_name = line.split(':')[0].strip();
						if (user_name == "root")
					
###摘要變數 (summary variable) (1/2)
						if (request.user.id == document.owned_id) {
							// 使用者可以編輯
						}
						
						...
						if (request.user.id != document.owned_id) {
							// 文件狀態是唯讀
						}
					
###摘要變數 (summary variable) (2/2)
						final boolean user_owns_document = (request.user.id == document.owned_id);
						
						if (user_owns_document) {
							// 使用者可以編輯
						}
						
						...
						if (user_owns_document) {
							// 文件狀態是唯讀
						}
					
###利用笛摩根定律 (De Morgan's law) 1. not (a or b or c) <=> (not a) and (not b) and (not c) 2. not (a and b and c) <=> (not a) or (not b) or (not c)
							if(!(file_exists && !is_protected)) {
								Error("Sorry, could not read file");
							}
					
v.s.
							if(!file_exists || is_protected) {
								Error("Sorry, could not read file");
							}
					
###誤用捷徑邏輯
						assert((!(bucket = Findbucket(key))) || !bucket->IsOccupied)
					
v.s.
						bucket = Findbucket(key);
						if (bucket != NULL) assert(!bucket->IsOccupied());
					
###與複雜邏輯搏鬥
						struct Range{
							int begin;
							int end;
							bool OverlapsWith(Range other);
						};
					
![Image of Overlaps](http://www.codeproject.com/KB/cs/DateRangeOverlapTesting/range_problem.jpg) ###實作OverlapsWith--檢查兩個段點是否位於other的範圍中
						bool Range::OverlapsWith(Range other) {
							return (begin >= other.begin && begin < other.begin) ||
							       (end < other.begin && end <= other.end) ||
							       (begin <= other.begin && end >= other.end);
						}
					
###從"相反方向解決問題"
						bool Range::OverlapsWith(Range other) {
							if (other.end <= begin) return false; // 他們在我們開始之前就結束
							if (other.begin >= end) return false; // 他們在我們結束之後才開始
							
							return true;
						}
					
###分解巨大的敘述(1/2)
						void update_highlight = function (message_num) {
							if ($("#vote_value" + message_num).html() === "Up") {
								$("#thumbs_up" + message_num).addClass("highlighted");
								$("#thumbs_down" + message_num).removeClass("highlighted");
							} else if ($("#vote_value" + message_num).html() === "Down") {
								$("#thumbs_up" + message_num).removeClass("highlighted");
								$("#thumbs_down" + message_num).addClass("highlighted");
							} else {
								$("#thumbs_up" + message_num).removeClass("highlighted");
								$("#thumbs_down" + message_num).removeClass("highlighted");	
							}
						}
					
###分解巨大的敘述(1/2)
						void update_highlight = function (message_num) {
							var thumbs_up = $("#thumbs_up" + message_num);
							var thumbs_down = $("#thumbs_down" + message_num);
							var vote_value = $("#vote_value" + message_num).html();
							var hi = "highlighted";
							
							if (vote_value === "Up") {
								thumbs_up.addClass(hi);
								thumbs_down.removeClass(hi);
							} else if (vote_value === "Down") {
								thumbs_up.removeClass(hi);
								thumbs_down.addClass(hi);
							} else {
								thumbs_up.removeClass(hi);
								thumbs_down.removeClass(hi);	
							}
						}
					
###Chapter 8 結語 * 解釋性變數好處 * 分解巨大的表示式 * 以有意義的名稱作為程式碼的說明 * 笛摩根定律 * 反轉問題或是考慮相反的目標