重生之我在男航學Java-2

TCxiaoli發表於2024-06-08

一、前言

  • 答題判題程式-4
  • 新增內容:選擇題,填空題,輸出順序的變化,考慮多個同學有多張不同試卷的答卷的情況
  • 新增知識點:抽象類的運用;
  • 在設計好前三次的題目集的情況下,將原本的題目類設計為抽象類(本來在第一次題目集的時候就可以如此設計,但是當時學的不夠多),同時將輸入的資訊進行判斷是否存在輸入錯誤,考慮對正規表示式的合理重新設計,雖然違背了開閉原則,但是也是實屬無奈。在經歷了前三次的猛烈打擊之後,我對設計原則的運用仍然不夠熟練,迫使我不得不做出違反其規則的決定,在此,我對傳道授業的老師表示抱歉......但是我也是在盡心盡力的完成任務了,雖然結果不怎麼理想,但是我覺得過程也是值得回味的
  • 家居強電電路模擬程式-1
  • 考查內容:類的設計(由於cai老師給出了類的設計,所以說設計並不是很難),正規表示式的應用,對java中集合框架的熟悉與應用(例如:ArrayList),高中物理......
  • 由於前幾次的答題判題程式放棄的人越來越多,心善的cai老師為我們花費心思重新編寫了一個題目以此來引導我們攻略P他的題目,在此對cai老師表示由衷的感謝。但是由於我的高中物理不是很好,還沒寫之前就對本次題目集充滿了恐懼,所幸cai老師一開始並沒有把題目設計得十分複雜,在我經歷了長達6小時的奮鬥,終於是拿到了分數,但是由於我在審題時不夠仔細(老毛病)導致我最終還是沒能拿下滿分。
  • 家居強電電路模擬程式-2
  • 新增內容:電阻,串聯和並聯,新的用電器(由於擔心我們做不下去,cai老師便只更新了一點點內容)
  • 在新增了一點點內容的前提下,對於我來說仍然是個巨大的挑戰,由於我自身的時間分配出現問題,導致我沒有用足夠的時間來對新增內容進行分析導致我沒有拿到一個期望的分數,並且由於我的在家居強電電路模擬程式-1正規表示式在家居強電電路模擬程式-2並不能完美適用,甚至於有些樣例根本沒辦法用,我不得不重新設計我的正規表示式,並且由於我的第一次沒拿到滿分的原因被我找到,我重新整理了在Main方法中的程式設計以此方便進行輸出和迭代。

二、設計與分析:

  • 答題判題程式-4
  • 類圖分析:
  • 從這張類圖中不難看出我其實只完成了對正規表示式的分析和實現,甚至並沒有對Question和Answer類進行抽象,此外實現了對資料的儲存並使用集合框架HashMap對其進行了儲存,因為我當時對抽象和繼承的理解感覺並不是十分深刻,導致了我對本次PTA可謂是舉步維艱,並且在當時感覺PTA真的不是給我這種人做的,我成了老師口中的“鴕鳥”,遇到困難就選擇了退縮,而不是奮發向前,因此我選擇在此對我的思路進行補充說明,以來彌補當時對此次PTA選擇漠視的過錯;
  • 1.對於Question和Answer類應該寫為一個抽象類,並讓其對應的選擇題,填空題對其進行繼承,答案也是對應題目有一種答案方式繼承於Answer;
  • 2.對於正規表示式進行修訂,對於每一個輸入都有對應的正規表示式進行匹配,此外還要對其輸入進行輸入資訊的判斷,判斷其輸入是否為一個正確的輸入;
  • 3.對於已經輸入並且正確的資訊進行儲存,按照正規表示式的解析對其進行對應的操作;
  • 上面這些文字看起來十分簡單,但是在真正實現時卻十分困難,你還要對儲存的資料考慮使用何種集合框架,以及如何合理的將不同的類聯絡起來,對其內容的解析如何拼接起來,這才是最考驗人的地方,希望我以後一次為誡,做一個面對困難迎難而上的人。
  • 家居強電電路模擬程式-1
  • 類圖分析:
  • 首先,我們考慮到由於在日常電路中存在串聯和並聯以及他們倆的各種混合,一開始我是打算將串聯和並聯分開進行設計,但是這樣子設計會導致如果竄並混聯就會使得串聯與並聯電路之間無法聯絡起來,所以,我根據老師的設計建議讓串聯和並聯都繼承了有一個共同的父類Circuit方便將其聯絡起來;
  • 其次,在電路中總的來說一共就倆種裝置,一種時控制裝置(例如:開關),另一種時被控制的裝置(例如:電燈),因此就需要建立倆個Circuit的子類但是又是控制裝置和被控裝置的父類,以此來避免程式碼的高度複用,同時考慮對其抽象(雖然我沒有對其進行抽象化......),並在最高層的類Circuit類中寫出print方法,方便後續對方法進行重寫和利用其進行資訊的輸出。
  • 另外,考慮到對輸入資訊的匹配過於複雜,專門設計一個Matcher類來對字串進行匹配,裡面的屬性主要是ArrayList inputs;ArrayList circuitArrayList = new ArrayList<>();一個用來儲存輸入的資訊,另一個則是對分析處理後的資訊進行儲存,同時在Matcher類中寫入public void buildCircuit(){(略)};方法,完成對電路裝置的寫入以及分析結果的儲存。
  • 最後在Matcher類中的public void buildCircuit(){(略)};方法中寫入對每一個資訊進行輸出即可。
  • 家居強電電路模擬程式-2
  • 類圖分析:

  • 由於在上一次題目集中看掉了這句話(按開關、分檔調速器、連續調速器、白熾燈、日光燈、吊扇的順序依次輸出所有裝置的狀態或引數。),同時理解錯了這句話(每個裝置一行,同類裝置按編號順序從小到大輸出)我不知道為什麼我把每個裝置一行理解成了每種裝置一行......然後由於沒注意到(按開關、分檔調速器、連續調速器、白熾燈、日光燈、吊扇的順序依次輸出所有裝置的狀態或引數。)這句話,在第一次設計中,我並沒有考慮到對每個型別都進行設計一個集合,導致我的最後那一點點分始終拿不到,附上圖:
  • 這是第一次中我主方法的寫法:(單純因為看掉了那句話,當時我無意間瞥見室友這麼寫還在想為什麼,這樣子傳引數好麻煩,搞半天我是小丑......)
  • 這是第二次看到了那句話之後主方法的寫法:
  • 由於在這次PTA中要開始考慮被控裝置的電阻問題,所以個頂層父類Device新增了一個屬性protected double resistance;在例項化物件物件的時候根據不同的裝置初始化為不同的值,例如白熾燈的電阻為10,如下圖:
  • 其中this.setResistance(10);便是對白熾燈電阻的初始化。
  • 此外,由於輸出資訊:同類裝置按編號順序從小到大輸出,在上一次中我是在Matcher類中實現的排序,違背了單一職責的原則,這次我將其單獨寫成了一個Sort類,其中包含
    ArrayList<K> kArrayList = new ArrayList<>();
    ArrayList<F> fArrayList = new ArrayList<>();
    ArrayList<L> lArrayList = new ArrayList<>();
    ArrayList<B> bArrayList = new ArrayList<>();
    ArrayList<R> rArrayList = new ArrayList<>();
    ArrayList<D> dArrayList = new ArrayList<>();
    ArrayList<A> aArrayList = new ArrayList<>(); 這些屬性,方便我對其包含的被控裝置進行分析和排序。其中的sort方法如圖所示:

    其實這樣寫就是在寫重複程式碼,合理的設計來說我應該專門寫一個氣泡排序的演算法,然後在利用這個方法對上述的每一個屬性進行排序可以大大減少程式碼量以及for迴圈的使用,避免程式碼的冗雜,
  • 在上一個類中雖然考慮了對並聯類的設計,但並沒有真正的實現並聯類,在這次PTA中由於迭代的需要,我必須加入並聯類,但由於並聯類中可能含有串聯電路,所以我把最開始打算設計為protected ArrayList deviceArrayList = new ArrayList<>();的屬性改為了protected ArrayList deviceArrayList = new ArrayList<>();,這樣使得我的並聯電路中不僅可以包含受控裝置,也可以包含串聯電路,同時在並聯電路中寫入並聯電路電阻的求法,串聯電路同理增加計算串聯電路電阻的方法。
  • 同時,由於新增了電阻屬性,需要對電壓重新進行分析,因此便有了Analyse類專門對其中經過了電阻的計算後來對電壓進行分析,由於總體上來說就是一個大的串聯中包含了一個並聯電路,並且在最大的電路中接入VCC的一定時控制裝置,因此可以在此直接調節輸出後的電,分析時首先在串聯電路中第電壓和電阻成正比進行計算後,接著考慮並聯電路中電壓相等,但是並聯電路中又有小的串聯電路,即又要對其進行思考分壓問題。
  • 此外,分析後分析並不需要考慮引腳的問題,因此我對正規表示式進行了改進,將原先對很多資訊都進行確切的匹配改為了對其進行模糊匹配,即每次只匹配輸入資訊[]中的後面半截資訊即可處理整個電路的資訊,更改前如圖所示:

    更改後如圖所示:

三、採坑心得:

  • 答題判題程式-4
  • 由於我的時間分配出現了問題,導致我未能及時完成這個題目集,我以後一定不會再犯這種錯誤了,嗚嗚嗚
  • 家居強電電路模擬程式-1
  • 眼瞎,沒看見一句話,導致了出現重複裝置的地方我一開始並沒有對其進行排序,造成了如此後果
  • 我在Matcher類中增加了排序演算法後
  • 但是仍存在幾個測試點拿不到分
  • 在題目集關閉後,我與同學和交流中發現我又少注意了一些題目資訊(按開關、分檔調速器、連續調速器、白熾燈、日光燈、吊扇的順序依次輸出所有裝置的狀態或引數)這使得我在最開始對資料進行如何儲存時的思考產生了極大的偏差,導致在輸出時無法完成如上資訊的合理輸出,是得最後四個測試點一直過不了。嗚嗚嗚......我以後一定要認真看題目了!!!
  • 在最開始的時候以為所有電壓資料應該為int型別,但由於發現在中途計算時有些資料跟測試點存在極小的偏差,直到看到這句話(為避免精度的誤差,所有有可能出現小數的數值用double型別儲存並計算),於是我急急忙忙便將所有跟計算有關的資料全部改成了double型別。
  • 此外,最後幾個測試點應該還烤爐又多個開關的情況,要所有開關閉合之後電路才能形成通路,但是我一開始在此次PTA中並沒有考慮此情況,導致了許多測試點都過不了

    (這其中出現的格式錯誤是因為有的輸出忘了換行,哈哈.......)
    於是我在Matcher類中進行了如下修改

    以此來判斷是否所有的開關都關上了,如果沒有的話就將整個電路的電壓設定為0,改後如圖:
  • 家居強電電路模擬程式-2
  • 由於出現了並聯和串聯的識別符號,得對正規表示式進行大改,但在改進後發現group組會捕獲不到所需的物件,即出現非零返回,後面發現時捕獲組的設定出現了偏差,將其修正即可......
  • 最開始對電路的理解不透徹,以為所有都得拆開分析,後面發現並聯電路和串聯電路倆可以一整個在一起分析,思路更改前:

    思路更改後:

    抽象的是,我不知道為什麼改了之後連樣例都過不去了,嗚嗚嗚.......
  • 更加令人匪夷所思的是,明明我的串聯電路的總電阻沒有問題,但是每次計算之後的並聯電阻和就為0,在除錯過程中也出現了並聯總電阻為Infinity且在我所有的資料均為double的情況下,一個人悄悄地碎了......

四、改進建議:

  • 答題判題程式-4
  • 合理的規劃時間,正確在上一次的基礎上進行迭代,考慮清楚如何在不違反開閉原則的基礎上完成對其迭代的合理設計。
  • 家居強電電路模擬程式-1
  • Matcher類中的if判斷多得超乎我的想象,並且程式碼相似度極高,造成了整體的冗雜以及嚴重違背單一職責原則,可以將此處封裝在一個專門的分析類裡面的方法,只需要對其傳參呼叫即可,這樣既解決了開閉原則,又完美的符合了單一職責原則,並且在後續的迭代中也只需要建立子類去繼承其父類對其分析即可,大大增加了程式碼的迭代性。
  • 此處的作用是對其開關進行判斷,也可以將其單獨拿出來做一個類來解耦,避免程式碼的耦合性過高,並且為每一條通路可以設定一個boolean屬性的變數專門來判斷這條路是否是一個通路。
  • print函式巢狀在了一個巨大的迴圈裡面,可以將其單獨設計成一個Print類,利於實現單一職責和解耦,並且使程式碼的邏輯性更清晰,同時也實現了開閉原則。
  • 家居強電電路模擬程式-2
  • 在Analyse中實現了分析並聯的方法,實際上可以將這個類進行抽象化,並且將分析功能寫入繼承它的子類當中,實現方法的重寫,降低程式碼的耦合性,同時避免了強制型別轉換會出現的各種錯誤,這樣還可以少去for迴圈的多重巢狀。
  • 計算電壓可以單獨做成一個計算類,將這個方法寫入其中,到時候利用泛型進行傳參即可,這樣做也是為了單一職責的原則以及開閉原則和降低程式碼的耦合性。
  • 此處的print利用了多次迴圈,實際上可以將其做成一個方法之後,只需要傳入引數呼叫就好了,避免了程式碼的高度重複。

五、總結

  • 1.學到了什麼
  • 其實cai老師為了我們也是操碎了心,又重新編寫一個題目,PTA說白了其實就是要我們利用課堂上的知識來對題目進行分析後給出合理的設計,但是我也不知道為什麼,寫的時候根本就想不到那麼多了,其實每次寫PTA基本上沒怎麼用到物件導向的設計模式,在此對我的授課duan老師說一聲抱歉。在PTA中我更最多的使學到了物件導向的原則的重要性,例如:單一職則原則,如果不能實現單一職責的原則,你會發現程式碼寫到最後思路越寫越亂,類與類之間的耦合性極高,可能可以跑得懂,但一定是令人頭大的程式碼;開閉原則和依賴倒轉實際上也是PTA所讓我們所熟悉的倆大原則,因為P他的作業都需要進行迭代,導致你如果不在第一次寫的時候就考慮後面的事情,就會令自己在後面的迭代中寸步難行,充分體現了物件導向的思想在PTA中的應用。
  • 2.我該做什麼
  • 實際上,我對duan老師所講述的物件導向的設計模式十分感興趣,上課的時候聽的十分認真,但下課了就不願意接著鑽研課上的PPT,我知道這是一種很不好的習慣,我會在接下來的日子裡行動起來。然後就是感覺很難做到真正意義上的知行合一,即我在課上的學習的知識很難在課後作業中運用起來,就算是duan老師上課講其它例子我也感覺我很難運用,就是感覺腦子裡面很多東西,但是我不知道到底該用哪一個去解決問題,不知道是不是自己對duan老師所講的知識沒有深度理解的原因,但不得不說,duan老師講課的水平是一流的,但是感覺duan老師個人不是怎麼喜歡講課,我表示理解,畢竟沒人會喜歡上班,誰不想躺著掙錢呢,haha
  • 3.做出怎樣的改變
  • 不知不覺大一就快過去了,對於物件導向這門課感覺可能就學會了(bushi)duan老師上課所講述的物件導向的設計模式,並且還是在自己並不能靈活運用的情況下,嗚嗚嗚...另外就是腦子裡滿是物件導向的七大原則,但是經常說在嘴邊的就是什麼單一職責,開閉原則,迪米特法則這幾個,說實話,跟物件導向的設計模式一樣,即使腦子裡有這些東西,感覺在運用的時候也不清楚到底用上沒有,單一職責有時候實現了,有時候又會忘記。說到底,還是缺少練習,我應該做一個什麼樣的人,我自己都有,但是難以走出自己的舒適圈,我應該做出改變了!!!

相關文章