自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

表驅(qū)動(dòng)法,邏輯控制優(yōu)化利器

開發(fā) 前端
對(duì)簡(jiǎn)單的情況而言,使用邏輯語(yǔ)句更為容易和直白,但隨著邏輯鏈的越來越復(fù)雜,查表法也就愈發(fā)顯得更具有吸引力。

本文轉(zhuǎn)載自微信公眾號(hào)「架構(gòu)精進(jìn)之路」,作者張張。轉(zhuǎn)載本文請(qǐng)聯(lián)系架構(gòu)精進(jìn)之路公眾號(hào)。

最近好多同學(xué)在開發(fā)過程中談到設(shè)計(jì)表結(jié)構(gòu)的一些idea,為了讓大家少走一些彎路,今天就計(jì)劃聊聊表驅(qū)動(dòng)法吧~

1、概念介紹

表驅(qū)動(dòng)法 是一種編程模式,從表里查找信息而不使用邏輯語(yǔ)句(if/else)

事實(shí)上,凡是能通過邏輯語(yǔ)句來選擇的事物,都可以通過查表來選擇。

對(duì)簡(jiǎn)單的情況而言,使用邏輯語(yǔ)句更為容易和直白,但隨著邏輯鏈的越來越復(fù)雜,查表法也就愈發(fā)顯得更具有吸引力。

應(yīng)用原則

適當(dāng)?shù)那闆r下,采用表驅(qū)動(dòng)法,所生成的代碼會(huì)比復(fù)雜的邏輯代碼更簡(jiǎn)單,更容易修改,而且效率更高。

2、應(yīng)用實(shí)踐

2.1 直接訪問

2.1.1 今天周幾?

傳統(tǒng)寫法:

  1. String today = "周日"
  2. Switch( dayForMonth % 7 ){ 
  3.     case 0 :  
  4.         today = "周日"
  5.     case 1 :  
  6.         today = "周一";    
  7.     case 2 : 
  8.         today = "周二";    
  9.     case 3 : 
  10.         today = "周三";    
  11.     case 4 : 
  12.         today = "周四";    
  13.     case 5 : 
  14.         today = "周五";    
  15.     default
  16.         today = "周六";    

表驅(qū)動(dòng)法:

  1. String [] weekday = new String[]{"周日","周一","周二","周三","周四","周五","周六"}; 
  2.   String today = weekday [ dayForMonth % 7 ]; 

2.1.2 每個(gè)月多少天?

傳統(tǒng)寫法:

  1. if(1 == iMonth) { 
  2.   iDays = 31; 
  3. else if(2 == iMonth) { 
  4.   iDays = 28; 
  5. else if(3 == iMonth) { 
  6.   iDays = 31; 
  7. else if(4 == iMonth) { 
  8.   iDays = 30; 
  9. else if(5 == iMonth) { 
  10.   iDays = 31; 
  11. else if(6 == iMonth) { 
  12.   iDays = 30; 
  13. else if(7 == iMonth) { 
  14.   iDays = 31; 
  15. else if(8 == iMonth) { 
  16.   iDays = 31; 
  17. else if(9 == iMonth) { 
  18.   iDays = 30; 
  19. else if(10 == iMonth) { 
  20.   iDays = 31; 
  21. else if(11 == iMonth) { 
  22.   iDays = 30; 
  23. else if(12 == iMonth) { 
  24.   iDays = 31; 

表驅(qū)動(dòng)法:

把邏輯寫成 map 或是 list,一目了然,可以搞個(gè)2維數(shù)組還加上了閏年的邏輯。

  1. const monthDays = [ 
  2.   [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], 
  3.   [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] 
  4.  
  5. function getMonthDays(monthyear) { 
  6.   let isLeapYear = (year % 4 === 0) && (year % 100 !== 0 || year % 400 === 0) ? 1 : 0 
  7.   return monthDays[isLeapYear][(month - 1)]; 
  8.  
  9. console.log(getMonthDays(2, 2000)) 

2.2 索引訪問

有時(shí)只用一個(gè)簡(jiǎn)單的數(shù)學(xué)運(yùn)算還無法把 age 這樣的數(shù)據(jù)轉(zhuǎn)換成為表鍵值,這種情況可以通過索引訪問的方法加以解決。

索引應(yīng)用:先用一個(gè)基本類型的數(shù)據(jù)從一張索引表中查出一個(gè)鍵值,然后在用這一鍵值查出需要的主數(shù)據(jù)。

舉例:

有100件商品,商店物品編號(hào)(范圍 0000-9999)

創(chuàng)建兩張表:索引表(0-9999),物品(查詢)表(0-100)

索引訪問有兩個(gè)優(yōu)點(diǎn):

  • 如果主查詢表的每條記錄都很大,那創(chuàng)建一個(gè)浪費(fèi)了很多空間的數(shù)組所用的空間,要比建立主查詢表所用的空間小得多。
  • 操作索引中的記錄比操作主查詢表的的記錄更方便,編寫到表里面的數(shù)據(jù)比嵌入代碼的數(shù)據(jù)更容易維護(hù)。

2.3 階梯訪問

這種訪問方法不像索引結(jié)構(gòu)那樣直接,但是它要比索引訪問方法節(jié)省空間。

階梯結(jié)構(gòu)的基本思想:表中的記錄對(duì)于不同數(shù)據(jù)范圍有效,而不是對(duì)不同的數(shù)據(jù)點(diǎn)有效。

舉例:

一個(gè)等級(jí)評(píng)定的應(yīng)用程序,其中“B”記錄所對(duì)應(yīng)的范圍是 75.0%-90.0%

>= 90.0% A

<90.0% B

<75.0% C

<65.0% D

<50.0% F

這種劃分范圍用在查詢表中是不合適的,因?yàn)槟悴荒苡煤?jiǎn)單的數(shù)據(jù)轉(zhuǎn)換函數(shù)來把表鍵值轉(zhuǎn)換成 A-F 字母所代表的等級(jí)。用索引也不合適,因?yàn)檫@里用的是浮點(diǎn)數(shù)。

在應(yīng)用階梯方法的時(shí)候,必須謹(jǐn)慎的處理范圍的端點(diǎn)。

  1. Dim rangeLimit() As Double = {50.0, 65.0, 75.0, 90.0, 100.0} 
  2. Dim grade() As String={"F""D""C""B""A"
  3. maxGradeLevel = grade.Length - 1 
  4.  
  5. // assign a grad to a student based on the student's score 
  6. gradeLevel= 0  
  7. studentGrade = ”A"  
  8. while( studentGrade = "A" and gradeLevel < maxGradeLevel )      
  9.   if( studentScore < rangeLimit( gradeLevel ) ) then          
  10.     studentGrade = grade ( gradeLevel)      
  11.   end if     
  12.   gradeLevel = gradeLevel + 1  
  13. wend 

與其他表驅(qū)動(dòng)法相比,這種方法的優(yōu)點(diǎn)在于它很適合處理那些無規(guī)則的數(shù)據(jù)。

在使用階梯訪問時(shí)需要注意的一些細(xì)節(jié):

1)留心邊界端點(diǎn)

注意邊界:< 與 <=,確認(rèn)循環(huán)能夠在找出最高一級(jí)區(qū)間后恰當(dāng)?shù)亟K止。

2)考慮用二分查找取代順序查找

如果列表很大,可以把它替換成一個(gè)準(zhǔn)二分查找法,從頭查找是很耗費(fèi)性能的

3)考慮用索引訪問來取代階梯訪問

階梯訪問中的查找操作可能會(huì)比較耗時(shí),如果執(zhí)行速度很重要,那可以考慮用索引訪問來取代階梯查找,即以犧牲存儲(chǔ)空間來?yè)Q取速度。

2.4 構(gòu)造查詢鍵值

如上述例子,我們希望能夠?qū)?shù)據(jù)作為鍵值直接訪問表,這樣既簡(jiǎn)單又快速。

但是問題或者數(shù)據(jù)通常并不是這樣友好,那就需要引出 構(gòu)造查詢鍵值 的方法。

費(fèi)率與年齡、性別、婚姻及交費(fèi)年數(shù)等不同情況而變動(dòng)。

1)復(fù)制信息從而能夠直接使用鍵值

age補(bǔ)齊:50 歲以上的年齡都復(fù)制一份 50 歲的費(fèi)率。

這樣優(yōu)點(diǎn)在于表自身結(jié)構(gòu)非常簡(jiǎn)單那,訪問表的邏輯也很簡(jiǎn)單;

缺點(diǎn)在于復(fù)制生成的冗余信息會(huì)浪費(fèi)空間,也即是利用空間換效率。

2)轉(zhuǎn)換鍵值以使其能夠直接使用

費(fèi)率表查詢時(shí),用一個(gè)函數(shù)將 age 轉(zhuǎn)換為另一個(gè)數(shù)值。

在此例子中,該函數(shù)必須把所有介于 0-5 直接的年齡轉(zhuǎn)換成一個(gè)鍵值,例如 5,同時(shí)把所有超過 50 的年齡都轉(zhuǎn)換成另一個(gè)鍵值,例如 50。

這樣在檢索前可以用 min()和 max()函數(shù)來做這一轉(zhuǎn)換。

例如,你可以用下述表達(dá)式:max(min(50, age), 17) 來生成一個(gè)介于 17-50 之間的表鍵值。

3)把鍵值轉(zhuǎn)換提取城獨(dú)立子程序

如果你必須要構(gòu)造一些數(shù)據(jù)來讓它們像表鍵值一樣使用,那就把數(shù)據(jù)到鍵值的轉(zhuǎn)換操作提取成獨(dú)立的子程序。這樣可避免在不同位置執(zhí)行了不同的轉(zhuǎn)換,也使得轉(zhuǎn)換操作修改起來更加容易。

任務(wù)是個(gè)方法,不再是數(shù)值了,這里我們可以利用 Dart 這樣的支持高階函數(shù)的語(yǔ)言特性,把方法當(dāng)做一個(gè)對(duì)象存儲(chǔ)在表中。

  1. var data = <String, Map>{ 
  2.     "A": { 
  3.       "name""AA"
  4.       "action": (name) => print(name + "/AA"), 
  5.     }, 
  6.     "B": { 
  7.       "name""BB"
  8.       "action": (name) => print(name + "/BB"), 
  9.     }, 
  10.   }; 
  11.    
  12.   var action = data["A"]["action"]; 
  13.   action("kk"); 

3、總結(jié)

1)如何從表中查數(shù)據(jù)?

  • List item
  • 直接訪問
  • 索引訪問
  • 階梯訪問

2)在表里存些什么?

  • 數(shù)據(jù)
  • 動(dòng)作(action)-描述該動(dòng)作的代碼/該動(dòng)作的子程序的引用。

表驅(qū)動(dòng)法提供了一種復(fù)雜的邏輯和繼承結(jié)構(gòu)的替換方案。如果你發(fā)現(xiàn)自己對(duì)某個(gè)應(yīng)用程序的邏輯或者繼承關(guān)系感到困惑,那是否可以通過一個(gè)查詢表來加以簡(jiǎn)化。

  • 使用表的關(guān)鍵決策是決定如何去訪問表,可以采取直接訪問、索引訪問或階梯訪問
  • 使用表的另一項(xiàng)關(guān)鍵決策是決定如何去把什么內(nèi)容放入表中
  • 需要保存浮點(diǎn)數(shù)和范圍數(shù)時(shí),使用階梯訪問的形式。

 

責(zé)任編輯:武曉燕 來源: 架構(gòu)精進(jìn)之路
相關(guān)推薦

2022-10-10 08:24:15

編程數(shù)據(jù)邏輯語(yǔ)句

2023-07-19 12:24:48

C++constexpr?語(yǔ)句

2018-05-23 13:47:28

數(shù)據(jù)庫(kù)PostgreSQL查詢優(yōu)化

2011-09-16 13:15:38

SQL Server優(yōu)化

2010-06-11 14:25:08

通信協(xié)議

2010-04-20 11:31:26

Oracle邏輯結(jié)構(gòu)

2011-11-28 10:50:56

JavaJVM優(yōu)化

2014-03-14 14:03:55

系統(tǒng)優(yōu)化達(dá)夢(mèng)集群

2017-12-12 14:26:16

數(shù)據(jù)庫(kù)PostgreSQL邏輯優(yōu)化

2009-11-16 10:30:24

Oracle驅(qū)動(dòng)表

2011-03-21 14:27:15

數(shù)據(jù)庫(kù)優(yōu)化業(yè)務(wù)邏輯設(shè)計(jì)

2017-10-10 14:56:13

GatherSDN帶內(nèi)控制

2021-08-17 10:39:54

SQL Server數(shù)據(jù)庫(kù)優(yōu)化

2024-04-03 09:12:03

PostgreSQL索引數(shù)據(jù)庫(kù)

2024-09-26 17:45:36

2017-02-28 17:46:15

Linux驅(qū)動(dòng)技術(shù)并發(fā)控制

2017-11-06 17:16:55

Linux設(shè)備驅(qū)動(dòng)并發(fā)控制

2009-08-31 16:29:21

C#控制輸入法

2023-07-24 09:00:00

數(shù)據(jù)庫(kù)MyCat

2013-01-25 11:15:56

RHEV
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)