面向對象課程做業1-3總結分析

 

  將近一個月的面向對象學習,做爲一個JAVA新晉選手,針對把「面向過程式封裝」思惟逐步過渡爲「基於數據管理與分工交互的面向對象」思惟的努力從未止步,回首前三次做業的學習痕跡,看到的不僅是本身進步的過程,更是提升的空間。java


 設計技巧總結 正則表達式


  增強設計魯棒性的基礎——基於正則的錯誤輸入的準確識別與反饋數組

  一個程序想要正確運行的重要前提是對異常輸入的識別和攔截。關於正則表達式的語法學習再也不贅述。安全

  經過三次練習,結合本身和被測程序的設計思路能夠發現,使用正則表達式識別錯誤主要有兩種思路——總體匹配和局部位置匹配,在實踐過程當中發現使用二者各有優缺點。  網絡

  當不須要很是準確的定位輸入的錯誤位置時,咱們更傾向於總體匹配。總體匹配是一種正向思路,對完整正確的輸入模式進行格式歸納,設計出匹配表達式,當輸入與表達式不能無縫匹配時,說明輸入不符合要求。優勢是不用分類窮舉全部的錯誤情形,減小了窮舉不全的失誤,非黑即白的有限衡量標準使得在各種非法測試中表現的很是穩。當正確輸入的標準能夠適當放寬時易修改,同時避免納新後的誤判。缺點是不易定位出不合規定的錯誤輸入位置,稍顯不友好,若是總體匹配代碼設計不佳長度過長在大規模輸入中可能爆棧。併發

  咱們以電梯類的總體匹配輸入檢測爲例,能夠發現全部合法輸入經過這四個表達式便可徹底描述,簡潔清晰。框架

1     private String checkpattern_1="^\\(FR\\,(\\+)?0{0,}1\\,UP\\,(\\+)?0{0,}(\\d+)\\)$"; 2     private String checkpattern_2="^\\(FR\\,(\\+)?0{0,}10\\,DOWN\\,(\\+)?0{0,}(\\d+)\\)$"; 3     private String checkpattern_3="^\\(FR\\,(\\+)?0{0,}[2-9]\\,(UP|DOWN)\\,(\\+)?0{0,}(\\d+)\\)$"; 4     private String checkpattern_4="^\\(ER\\,(\\+)?0{0,}([1-9]|10)\\,(\\+)?0{0,}(\\d+)\\)$";

 若是修改樓層範圍、上下行命令限制、前導0的個數和符號限制等,很是少的改動便可實現。注意此處^....$的正則組合用於限制正確輸入的開頭結尾符號,避免匹配到一個非法表達式的正確子串,致使判斷錯誤。eclipse

   若是想將錯誤定位細化到返回錯誤字符周圍環境,且字符種類比較少、字符搭配限定較侷限時,位置匹配是一種比較好的策略。它列舉每一種字符先後的合法搭配,巧用^,使得若是有匹配結果說明存在非法搭配,必要時返回匹配到的字符串便可。優勢是定位準確便於輸入者修改,缺點卻比較明顯,當字符串種類多且搭配普遍時,不免存在列舉遺漏,BUG也就被掛在樹上了。ide

 咱們以多項式計算程序輸入爲例,一種識別「(」的位置檢查設計和實驗結果以下:函數

 2         String pattern ="\\([^\\d\\+\\-]";   再配合數字的位置合法性判斷,當輸入爲{1,(1,2)}時,輸出爲 #1,(

  重用代碼封裝,簡化信息傳遞,營造類的專屬「內部生態

  重用代碼封裝——修改少,邏輯清

  咱們對不一樣的信息類型處理雖然不盡相同,但模式上是大同小異的。多項式對多項式的信息抽取、結果記錄過程是同樣的,運算過程只有一個‘+’、‘-’之別,徹底能夠將相同操做合併。電梯的FR、ER請求信息雖然不一樣,但均可以抽象爲請求類,使用一套相同的屬性設計去刻畫。捎帶電梯處理一條主請求和一條捎帶請求雖然對一些狀態的修改不徹底一致,但運行一條指令並刪除其同質指令的流程是一致的,若是徹底割裂直接分兩類,那麼給電梯解析請求併發送指令以及刪除同質指令的代碼就會被重複書寫,一旦設計存在漏洞,須要修改多處,代碼量大就很容易疏忽掉一處,在少許測試下不易發現,埋下了隱患。

      簡化信息傳遞——交互智能,安全性強

  有些信息沒必要暴露在其餘類面前,由於類的內部對自身變量的分析能夠給出傳達給外部的內部狀態,而其餘類只要獲知這種狀態就知道本身的行動目標了,解析的過程是一種冗餘,對數據存儲也不安全,不便於調試。例如調度類和電梯類的交互,電梯沒必要獲知調度類目前正在解析的指令是FR仍是ER等詳細信息,不須要記錄本身執行過的指令歷史,只須要遵從調度類有限輸出信息的指揮,知道本身要去幾樓便可,而調度類也只須要知道電梯的當前時間、上下狀態、預計到達各個樓層的時間便可爲電梯準備下一個command,至於記錄下上一調指令的信息便於篩選下一條是調度類的「分內之事」,不須要和別人商量,儘量少的變量共享也就意味着減小誤修改、下降分析複雜度,由於分工明確,變量私有,內部運營,DEBUG調試也輕鬆許多。

  營造類的專屬「內部生態」——測試完備,定位輕鬆

  若是一個類能夠「自給自足的」提供啓動信息、輸出運營結果,那麼測試類的功能性就變得很簡單。測試技巧是在類的內部設計一個main函數,每寫完一個就進行功能測試,把BUG消滅在底層,防止整個工程build後漏洞百出在總體的視角分段debug。

  給方法買人身保險——try-catch維持程序穩定性

  設計時把每一個方法都放到try-catch裏面並進行必定的容錯處理,輸出本身設定的報錯信息並使程序正常退出實是明智之舉。一方面完全排除crash的可能性,加強程序運行的穩定性可靠性,一方面運行後若是出現異常,會輸出本身預先設計好的信息,直接能夠定位到出錯的方法,給猜測錯誤緣由環節和調試修改環節帶來了不少方便。使用格式舉例:

1 ·  try{ 2  .....代碼.......... 3    }catch(Exception e) { 4             System.out.println("# calculate函數出現異常"); 5             System.exit(0);//容錯機制能夠根據須要設計 6     }catch(Error e) { 7             System.out.println("# calculate函數出現錯誤"); 8             System.exit(0); 9     }

  統一基礎上的個性化——繼承

  以課上公司員工和課下電梯調度類爲例,這種調用父類的有層次感的方式很是易於創造出統一性和個性化兼備的代碼邏輯,便於修改,同時能夠實現父類和子類的切換。應該注意的是繼承關係中構造函數的使用。

(1)子類的構造過程當中必須調用其父類的構造方法。 (2)子類能夠在本身的構造方法中使用 super(argument_list)調用父類的構造方法,也使用 this(argument_list)調用本類的另外構造方法。若是調用 super,必須寫在子類構造方法的第一行。 (3)若是子類的構造方法中沒有顯式調用父類的構造方法,則系統默認調用父類的無參數構造方法。 (4)若是子類構造方法中既沒有顯式調用父類的構造方法,而父類又沒有無參數的構造方法,則編譯出錯。

  其餘設計技巧——變量名設計有講究。天然語言記錄設計靈感,施工按照圖紙。使用PMD等工具對本身的代碼進行評估。

  變量名設計不能隨意,不然極可能形成寫代碼過程當中變量名誤寫,尤爲是當錯誤變量名也存在時,BUG就在不知不覺中產生了。能夠巧用'_'鏈接,縮寫易於識別,名稱表達變量的特色、用途。

   有些邏輯比較複雜的工程好比說電梯設計不建議直接上手寫代碼,一個可參考的方法是在文檔中用天然語言或圖表寫明設計框架,大概包括類的分工、一個類管理的屬性和各個方法接收的信息、主要內部運營邏輯、傳達出的信息效果以及方法間、對象之間信息交互的機制檢查後再開始寫碼,這種方式對間斷完成工程、邏輯debug提升效率很是有效。

  根據PMD反饋的查重複結果,能夠提示咱們將重複的部分進行封裝。他提示的if-else switch缺失等信息,也能夠幫助咱們儘快消滅潛在卻很難注意到的BUG。

【關於DEBUG...】

  關於if-else:可使用斷點調試對可疑處單步運行,也能夠設計標記變量測試是否進入該條件若是沒有就要查看哪一個變量錯誤致使條件不知足。

  關於跟蹤變量:重點跟蹤定位其在多個方法調用先後的區別,對比查看到異常變化。

  關於類的數組不易查看的屬性內容:能夠先跟蹤某一個存入數組前變量的值,如發現沒有異常再使用數組下標遍歷對象法查看實際存儲值。


做業自檢改進與BUG修復


  做業1——多項式運算

 做業重難點總結:

主要是初學者對正則表達式的學習使用,尤爲是屢次匹配一個字符等正則表達方案,正則表達式表達漏洞頗有可能致使意想不到的BUG。正則表達式匹配函數的使用,經常使用匹配函數以下。

一個Matcher對象是一個狀態機器,它依據Pattern對象作爲匹配模式對字符串展開匹配檢查。首先一個Pattern實例訂製了一個所用語法與 PERL的相似的正則表達式經編譯後的模式,而後一個Matcher實例在這個給定的Pattern實例的模式控制下進行字符串的匹配工做。

(以上兩圖來自網絡,不算太全面,放在這裏能夠方便你們查閱)

關於匹配次數:

[] 由方括號內的一個字符列表建立的自定義字符類 . 匹配任何單個字符 下面的字符將用於控制將一個子模式應用到匹配次數的過程: ? 重複前面的子模式0次到一次 * 重複前面的子模式0次或屢次 + 重複前面的子模式一次到屢次

筆者記性不太好因此emmmmmmmm就把本身用的幾個肥腸常見的代碼段貼在這裏之後直接用嘿嘿嘿嘿 -_-

* 匹配並把匹配結果放到一個數組裏面:

 1     Pattern p = Pattern.compile("([/+/-]?\\d+)|[\\-\\+]");  2     
 3         Matcher m = p.matcher(str);  4     
 5         List<String> strlist = new ArrayList<String>();  6     
 7         while(m.find()) {  8  strlist.add(m.group());  9  } 10     
11         Str = new String[strlist.size()]; 12     
13         int i=0; 14         for(String string : strlist) { 15             Str[i] = string; 16             i++; 17         }

* 讀入一波字符串並進行必定的操做

1      Scanner sc = new Scanner(System.in); 2         String str=null; 3         
4         if(sc.hasNextLine()) { 5             str = sc.nextLine();
        //進行某種鮮爲人知的操做 @_@
6 } 7 sc.close(); //必定不要忘了阿!!!!!

 * 關於一個字符串可能不方便一次性輸出但須要在視覺上是一行:

System.out.print() 結尾沒有換行符,很適合輸出半句話

System.out.println()結尾有換行符,適合輸出行尾

輸出時使用一個String變量拼接一個字符串是一個很好的辦法,JAVA裏面的‘+’簡直不能再好用了QAQ!!

      問題代碼段1:

 1 public class ComputePoly{  2  
 3    public void computer() {  4   Poly temp=new Poly(Split.len+1);  5   for(int i=0;i<Split.len+1;i++) {
6     temp.term[i]=Split.PolyList[0].term[i];
7   } 8 9 省略計算過程 10     ...... 11 } 12 public void print() {
        打印結果
13     ..... 14 } 15 }

  待提高提高技能點:一、多項式計算類直接訪問split產生的public多項式數組屬性,且修改了第一個數組元素的值,很是不安全。

           二、第一次寫面向對象程序,其實是「披着面向對象外衣的面向過程程序」,對計算類的分工不太明確,將print方法一併寫入了計算多項式類的方法中。

  解決方案:一、將split類數組屬性設爲Private但提供查看方法,值不容許寫入到第一個數組元素的位置,而是在ComputePoly類設計一個保存結果的Poly類的對象。

         二、ComputePoly類對外提供訪問private結果屬性的方法,打印經過另外一個類調用這個方法獲取信息並拼接字符串來實現。

       問題代碼段2: check方法中的20個對不一樣類符號位置合法性判斷的方法,舉其中兩個說明問題

 1 public void _1(String str) {  2         String pattern ="[^\\d\\)],";  3         
 4         Pattern r = Pattern.compile(pattern);  5         
 6         Matcher m = r.matcher(str);  7         
 8         List<String> ComLeList = new ArrayList<String>();  9         int flag=0; 10         while(m.find()) { 11             flag=1; 12  ComLeList.add(m.group()); 13  } 14         String[] ComLeBug = new String[ComLeList.size()]; 15         int i = 0; 16         for(String ComBug:ComLeList) { 17         ComLeBug[i] = ComBug; 18         i++; 19  } 20         if(flag==1) { 21             System.out.println("ERROR"); 22             for(int j=0;j<ComLeBug.length;j++) { 23                 System.out.println("#"+ComLeBug[j]); 24  } 25             exit=1; 26  } 27  } 28     
29     public void _2(String str) { 30         String pattern =",[^\\(\\d\\+\\-]"; 31         
32         Pattern r = Pattern.compile(pattern); 33         
34         Matcher m = r.matcher(str); 35         
36         List<String> ComLeList = new ArrayList<String>(); 37         int flag=0; 38         while(m.find()) { 39             flag=1; 40  ComLeList.add(m.group()); 41  } 42         String[] ComLeBug = new String[ComLeList.size()]; 43         int i = 0; 44         for(String ComBug:ComLeList) { 45         ComLeBug[i] = ComBug; 46         i++; 47  } 48         if(flag==1) { 49             System.out.println("ERROR"); 50             for(int j=0;j<ComLeBug.length;j++) { 51                 System.out.println("#"+ComLeBug[j]); 52  } 53             exit=1; 54  } 55     }

     解決方案:」方法間只有匹配串不一樣而檢測邏輯徹底相同,因此應該封裝爲一個以匹配正則串和待檢測字符串爲參數的方法。經過屢次調用減小代碼無用重複。

     其餘待提高技能點:善用try catch。

【BUG修復】

BUG: 輸入:{(1,2        錯誤輸出:{(1,2)}

     輸入 : {               錯誤結果:crash

    出錯緣由分析:局部位置匹配法設計出的正則匹配串用於檢索匹配到其餘字符的狀況,但若是是旁邊缺失則很難發現,甚至認爲是正確輸入繼續計算,gg了。

    方案修正:首先在這種環境下選用總體匹配可使代碼健壯性更強,若是必定要使用局部位置匹配須要對括號這種必須成對出現的符號有單獨判斷。最佳方案是使用總體匹配判斷輸入正誤,再用局部匹配反饋錯誤位置。添加try catch。

特別注意:

對回車、空格等空輸入的處理。

    做業2——傻瓜式電梯設計

 

做業重難點總結:

一、電梯類和調度類之間如何巧妙的交互??調度類怎麼指揮電梯??

二、調度類怎麼才能又快又準的排除同質請求並準備出一個新的請求?

三、如何使ER和FR既有不一樣又存在能夠合併處理的統一性?

四、對隊列的操做怎樣才能沒有BUG?刪除同質後下標必定要保持在原地而不是被加一再繼續檢查!!

 五、對同質的準確理解!!抓住ER和FR必定不是同質!

  問題代碼段1:

 

 1 sliptthenadd代碼段

 待提高技能點:split在寫法上存在很大優化空間,這是由於split封裝重用的空間很大,使用了20多個局部位置匹配函數致使對每一個字符串的處理都很費時間。split類中根據第一個有效字符是符號仍是數字分類,依次將信息存入多項式數組,但if和else的內部存儲的過程除下標差1外基本重複,使代碼量大幅度增長,給修改帶來了很大困難,也增大了出錯風險。分工不清,將split和add到隊列中的過程設計爲了一個方法,檢查數據範圍的過程重複書寫,多個報ERROR的else能夠統一設計爲1到2個ERROR。

  解決方案:將重複的部分封裝成一個存儲方法,不一樣的地方能夠傳入變更信息進行替換,這樣只須要調用這個存儲函數並傳入可變下標便可。分別爲分離數據和加入到隊列中的過程設計爲兩個方法,且使得方法對FR和ER指令都有必定的包容性。數字範圍檢查封裝設計。合併多個非法輸入的else。

  問題代碼段2:

將刪除同質請求並schedule出一個可執行的請求的方法實如今了請求隊列類。

    待提高技能點:準備一個新的可執行合法指令的職責屬於Scheduler類。請求隊列自己只對外提供刪除隊列元素、查看隊列元素、添加隊列元素的操做將使得思路更加清晰。

  解決方案:將這個自檢並調度函數改到Scheduler類。

  問題代碼段3:

Scheduler類的commander方法將取指令和對電梯發出調度信號一併書寫,致使第一條指令和非第一條指令關於調度發出信號的部分重複。

  解決方案:將取指令和解析指令發出調度信號分開,實際上是否是第一次取指令交給電梯區別不大,能夠合併。

雖然此次做業沒有被查到功能性BUG,但我認爲如下幾點值得注意:

一、若是控制指令執行條數是100條,則當使用變量++記錄數目並經過判斷變量大小決定是否可繼續讀入時,須要注意邊界條件的設計,尤爲是取等條件。 2、因爲隊列的變更幅度比較大,最好採用動態數組,在動態數組中要熟練設計查看、移除、添加元素的方法。 3、屬性一概設計爲Private,並非全部的屬性都須要對外提供get方法,儘可能減小提供get方法的機會,儘可能減小甚至杜絕提供set方法,必定要注意減小無心中的變量屬性共享,尤爲是數組屬性。 四、檢查輸入格式和數字範圍過程儘可能集中,利於修改。必定要大幅度改進封裝水平和抽象水平。

  做業3——可捎帶(ALS)電梯

做業重難點:

  此次做業主要是在理解捎帶策略的狀況下熟悉對tostring的重寫、Scheduler的繼承機制、接口的設計與實現等,對代碼的重複冗餘作了從新的封裝優化。Scheduler繼承了上次做業,主要繼承的是schedule方法,也就是排除同質的方法,同時本身還要補充順路捎帶的調度方法使用super來調用父類的內容。難點在於如何輕鬆的在父類和子類之間調用自如,而不是出現混亂。對繼承的理解須要藉助代碼多加觀察和練習。

  另外,發現大多數同窗出現BUG的緣由是對捎帶的邊界條件認識不清。此處牆裂推薦同窗們:一、能夠提前閱讀指導書作到心中有數,但等指導書穩定下來再寫代碼,不然極可能會帶着錯誤的認識寫了一套不合題意的代碼而後改的時候你就該哭唧唧了!二、指導書比較長,新建一個文檔把重點粘貼下來!作一波面向本身設計需求的從新整理!三、發現本身混亂的時候不是先求助別人而是先從新看指導書再和別人討論!不然極可能被越說越亂!

 

 

  因爲沒有被發現功能性BUG(主要問題是get set有點多說明數據管理分配還有待改善),下面將學習過程當中的疑難點作簡要總結:

  一、重寫和重載:

override(重寫)    1、方法名、參數、返回值相同。    2、子類方法不能縮小父類方法的訪問權限。    3、子類方法不能拋出比父類方法更多的異常(但子類方法能夠不拋出異常)。    4、存在於父類和子類之間。    5、方法被定義爲final不能被重寫。  overload(重載)   1、參數類型、個數、順序至少有一個不相同。   2、不能重載只有返回值不一樣的方法名。   三、存在於父類和子類、同類中。

  二、學習繼承中一個有趣的現象:

 1 public class TestExtend{  2     public static void main(String args[]){  3         Student s=new Student();  4  s.disp();  5  }  6 }  7   
 8 class Person{  9     int a; 10     public Person(){ 11         a=1; 12  } 13     public void disp(){ 14  System.out.println(a); 15  } 16 } 17   
18 class Student extends Person{ 19     int a; 20     public Student(){ 21         a=2; 22  } 23 }

  解析:運行上面的程序,輸出的是1仍是2?你會看到輸出的是1!

  上面的程序中Person和Student類中都有a屬性,咱們定義了一個Student的對象s,調用s的disp()方法輸出的不是Student的a而是Person的a。相信不少人在運行程序前都會以爲應該輸出2,但結果告訴咱們輸出的就是1!子類Student雖然覆蓋了父類的屬性a,但子類沒有重寫父類的disp()方法,對象s調用disp()方法時調用的依然是父類的方法,而父類方法訪問的依然是父類的a,而不是子類的a。這裏或者重寫父類的disp()方法,或者將Student中的int a;註釋掉才能輸出2!其實上面程序在邏輯上是有問題的,既然繼承了父類的屬性,就不該該在子類中新定義一遍,子類中能夠增長屬性,可是重寫屬性沒有什麼意義!  同時,子類對繼承來的屬性賦初值時,能夠經過調用super(屬性初值)也即父類的構造函數的方法。

  關於繼承的特色的總結:

1、子類只能繼承父類全部非私有的成員(成員方法和成員變量) 2、子類不能繼承父類的構造方法,可是能夠經過super關鍵字去訪問父類的構造方法。 
三、咱們何時考慮繼承?若是有兩個類A,B。只有他們符合A是B的一種,或者B是A的一種,就能夠考慮使用繼承
四、重寫某方法後子類仍然能夠返回父類的方法:使用super

       


三次做業可能涉及到的一些JAVA易混淆的關鍵字、特性等的介紹


 

有關static

static方法是靜態方法,沒有static的是非靜態方法。 靜態方法必須建立對象才能訪問非靜態成員。靜態方法能夠不建立對象,直接訪問靜態成員,也能夠經過建立對象來訪問。
static修飾的靜態方法會隨着類的定義而被分配和裝載入內存中,編譯器只爲整個類建立了一個靜態變量的副本,也就是隻分配一個內存空間,雖然可能有多個實例,但這些實例共享該內存,特別值得注意的是,任何一個對象對靜態數據成員的修改,都會影響其它對象。 
使用類名加前綴訪問靜態方法,使用實例化對象名訪問靜態方法。
靜態方法只能訪問靜態數據成員,非靜態方法能夠訪問靜態方法和非靜態方法,
非靜態方法能夠直接訪問非靜態數據成員和靜態數據成員。

參考代碼:

 1 import java.util.*;  2 
 3 public class TestStatic {  4     public static void main(String[]args){  5         System.out.println(S.getStatic());//使用類名加前綴訪問靜態方法
 6         S s=new S();  7         System.out.println(s.getStatic());//使用實例化對象名訪問靜態方法
 8  System.out.println(s.get());  9  } 10     public static class S 11  { 12         private static int a; 13         private int t=0; 14 
15         //靜態初始器:由static和{}組成,只在類裝載的時候(第一次使用類的時候)執行一次,每每用來初始化靜態變量。
16         static{ 17             a=10; 18  } 19 
20         //靜態方法只能訪問靜態數據成員
21         public static int getStatic() 22  { 23             return a; 24  } 25 
26         public int getT() 27  { 28             return t; 29  } 30 
31         //非靜態方法能夠訪問靜態方法和非靜態方法
32         public int get() 33  { 34  getT(); 35  getStatic(); 36             t=a;//非靜態方法能夠訪問非靜態數據成員和靜態數據成員
37             return t; 38  } 39  } 40 }

super用法總結:

第1、在子類構造方法中要調用父類的構造方法,用「super(參數列表)」的方式調用,參數不是必須的。同時還要注意的一點是:「super(參數列表)」這條語句只能用在子類構造方法體中的第一行。 第2、當子類方法中的局部變量或者子類的成員變量與父類成員變量同名時,也就是子類局部變量覆蓋父類成員變量時,用「super.成員變量名」來引用父類成員變量。固然,若是父類的成員變量沒有被覆蓋,也能夠用「super.成員變量名」來引用父類成員變量,不過這是沒必要要的。 第3、當子類的成員方法覆蓋了父類的成員方法時,也就是子類和父類有徹底相同的方法定義(但方法體能夠不一樣),此時,用「super.方法名(參數列表)」的方式訪問父類的方法。

關於final關鍵字:

 

它的主要用法有如下四種: 用來修飾數據,包括成員變量和局部變量,該變量只能被賦值一次且它的值沒法被改變。對於成員變量來說,咱們必須在聲明時或者構造方法中對它賦值; 用來修飾方法參數,表示在變量的生存期中它的值不能被改變; 修飾方法,表示該方法沒法被重寫; 修飾類,表示該類沒法被繼承。 上面的四種方法中,第三種和第四種方法須要謹慎使用,由於在大多數狀況下,若是是僅僅爲了一點設計上的考慮,咱們並不須要使用final來修飾方法和類。

 

this用法總結:

 第1、經過this調用另外一個構造方法,用發是this(參數列表),這個僅僅在類的構造方法中,別的地方不能這麼用。 第2、函數參數或者函數中的局部變量和成員變量同名的狀況下,成員變量被屏蔽,此時要訪問成員變量則須要用「this.成員變量名」的方式來引用成員變量。固然,在沒有同名的狀況下,能夠直接用成員變量的名字,而不用this。 第3、在函數中,須要引用該函所屬類的當前對象時候,直接用this。 其實這些用法都是從對「this是指向對象自己的一個指針」這句話的更深刻的理解而來的。


測試用例設計策略


 

  一般是使用分支樹不重不漏的進行測試,主要的測試思想是先總體聯合後局部深刻,也即先對幾個功能進行捆綁性測試,若是發現有問題再進一步細化測試直到排查出具體錯誤功能重點測試一些違反正常思惟的狀況。

  對本身的測試須要先測試輸入再測試處理功能,對同窗互測的程序須要針對其代碼設計猜測其最有可能出現漏洞的地方進行鍼對性優先測試,主要是先功能後輸入,設計針對性的設計樣例。

  這就涉及到讀對方的代碼,不要求所有讀懂,但要對其處理邏輯心中有數,由於可能他的處理邏輯自己就有漏洞,有必要時能夠選用流程圖的方式輔助認識其處理運行邏輯。能夠結合其公測被測狀況設計出公測可能沒有測試到的但設計思惟相同的樣例,好比公測發現其對ER的處理有問題,那麼能夠優先測試其對FR的類似處理是否是有問題。

對於輸入型測試:

主要測試思路爲:簡單標準型、邊界正確型、邊界錯誤型、隨機輸入型、大規模輸入壓力測試型

對於功能型測試:

主要測試思路爲:基礎功能型、不知足處理條件正常退出型、多種被處理情形尤爲包括邊界狀況知足被處理條件的情形。尤爲注意一些極端狀況的測試和維護。

下面對三次做業的重點測試類型概括並對經典測試樣例舉例:

做業1特殊樣例:第一個多項式前有無符號、異常字符、空多項式、階數或係數超大的多項式、單個多項式、負數階多項式、係數爲負的多項式、任意非法輸入(包括右大小括號的缺失以及只有一個括號等極端狀況的測試)

做業2特殊樣例:各類隨機輸入、1層和10層的FR指令方向特殊性、符號和前導0等、以2的32次方(4字節)爲邊界的合法和不合法測試、輸入時間亂序、同質請求測試(重點),首條指令的目標樓層在1層,多條相同或不一樣類型的指令連續對同層操做,FR、ER交替發出、同時發出等。

做業3特殊樣例:在做業2樣例的基礎上有意設計捎帶的邊界樣例,尤爲是對同層相同時間和不一樣時間包括開關門階段及邊界的反覆操做,以及對某一層的反覆請求,注意觀察被測程序對同質和選擇捎帶指令的順序,由於此處很容易出現邏輯漏洞。以及輸出順序的問題等。

 

 


總結


 

 耿直girl須要僞裝這裏有個總結——

總之由於是剛入門,本身的代碼即便在沒有BUG的狀況下也是很須要優化寫法的,明顯感受到如下幾點須要提起注意(相信也是大多數同窗的感覺):

一、命名要有意義有區分度。除了臨時循環變量不一樣類之間、不一樣階段之間儘可能不要出現命名徹底同樣的變量,很容易蒙圈QAQ。

二、必定要注意封裝重用!必定要注意封裝重用!必定要注意封裝重用!

三、必定要把握好全部的等號邊界!!

四、儘可能減小private變量的get set方法!交互要簡潔!

五、一個功能一次測試,事半功倍!

六、分工必定要準確有道,不可越俎代庖!!文檔是好助手!

七、try-catch

八、測試時越不合常規的狀況越要好好測!!邊界數據使用各類姿式測試很重要!暴力數據也要測!BUG出如今夾縫中!

九、代碼修改先不要刪,先註釋掉!沒準是你腦袋瓦特忽然改錯了!orz

十、必定要學會用eclipse調試,直接打印變量效率很低。

十一、readme不要自相矛盾emmm對於天然語言描述難令人理解的地方給出樣例說明!

十二、在通常的數組和動態數組之間...選動態數組好嗎!!動態數組省空間並且簡直不能再好用!

1三、整理指導書!書讀百遍,其義自見。

1四、不要懼怕學習沒用過的東西,java巧妙的地方有不少。百度一下,你就知道。

 要是還有沒說完的重點或者手殘寫錯的地方emmmmmmmm麻煩你們在評論區提醒下本智障嘻嘻謝= =!咱們下期再見!

相關文章
相關標籤/搜索