前言
時光飛逝,轉眼之間又過了兩週,又到了寫部落格的時候。經過這兩週的磨礪,我感覺自己的物件導向設計的技術有了很大的提升,但距離熟練還有較大的距離,每隔一段時間總結是對過去的一種回顧,更是一種學習和成長的過程。透過總結和回顧,可以加深對過去程式設計的經歷、學習的記憶和理解,有助於鞏固Java基礎知識,提升java學習效果。因此部落格還是要堅持寫下去。
PTA 家居強電電路模擬程式-3
在第二次的基礎上,這次迭代新加了互斥開關和窗簾,同時還增加了多個並聯電路串聯在一起的情況,互斥開關有3個引腳:1個是彙總引腳,另兩個是分支引腳。同時互斥開關也可以像正常開關一樣正反接,而且互斥開關接不同的分支引腳有不同的電阻,以上總總表明了這次迭代的難度。
PTA 家居強電電路模擬程式-4
這是家居強電電路模擬程式最後一次迭代,同時也是我認為這幾次PTA中最難的一次,不僅要輸出輸出該電器每個管腳的電壓,而且本次迭代,每個元器件都有最大電流的設定,當實時電流超過最大電流時,在該電器輸出資訊的最後加入提示“exceeding current limit error”,而且還增加了二極體這一迭代裝置,導致難度飆升。
設計與分析
家居強電電路模擬程式-1
設計
引腳類(Pin):存放引腳的資訊
protected double v = 0;//電壓預設為0
protected int id;//引腳的編號
protected int pinid;//判斷引腳是輸入引腳還是輸出引腳
public String type;/8引腳裝置所屬的型別
開關類(Switch):存放開關的資訊
private int id;//開關的編號
public Pin pin1;//開關的引腳
public Pin pin2;//開關的引腳
private boolean state;//開關狀態
public void print()//輸出資訊
調檔器(Governor):存放調檔器的資訊
protected int id;//調檔器的編號
public EnterPin pin1;//輸入引腳
public OutPin pin2;//輸出引腳
public void print();//輸出資訊
分檔調檔器(Governor):存放分檔調檔器的資訊
protected int id;//調檔器的編號
public EnterPin pin1;//輸入引腳
public OutPin pin2;//輸出引腳
private double[] grade = {0, 0.3, 0.6, 0.9};//分檔調檔器的檔位
private int gear;
public void print();//輸出資訊
連續調檔器(Governor):存放連續調檔器的資訊
protected int id;//調檔器的編號
public EnterPin pin1;//輸入引腳
public OutPin pin2;//輸出引腳
private double grade;//調檔器的檔位
public void print();//輸出資訊
燈類(Light):存放燈的資訊
protected int id;//燈的編號
public EnterPin pin1;//輸入引腳
public OutPin pin2;//輸出引腳
public void print();//輸出資訊
風扇類(Fan):存放風扇的資訊
protected int id;//風扇的編號
public EnterPin pin1;/輸入引腳
public OutPin pin2;//輸出引腳
public void print();//輸出資訊
匹配類(Matching):對輸入的資訊進行處理
public void match()//對輸入的資訊進行處理
方法類(Method):對資訊進行處理並輸出
public static void electrify();//計算每一個裝置的電壓
public static void printall();//將裝置資訊按順序進行輸出
電器工廠類(FacilityFactory):儲存所有的裝置資訊
public HashMap<Integer, Switch> switches = new HashMap<>();//所有開關
public HashMap<Integer, Gradegovernor> gradegovernors = new HashMap<>();//所有分檔調檔器
public HashMap<Integer, Continuousgovernor> continuousgovernors = new HashMap<>();//所有連續調檔器
public HashMap<Integer, Incandescentlight> incandescentlights = new HashMap<>();//所有白熾燈
public HashMap<Integer, Daylight> daylights = new HashMap<>();//所有日光燈
public HashMap<Integer, Ceilingfan> ceilingfans = new HashMap<>();//所有吊扇
public HashMap<Integer, Standfan> standfans = new HashMap<>();//所有落地扇
public ArrayList<Line> allLines = new ArrayList<>();//所有串聯電路
public ArrayList<Lines> lines = new ArrayList<>();//所有並聯電路
public HashMap<Integer, ExclusiveSwitch> exclusiveSwitches = new HashMap<>();//所有互斥開關
public HashMap<Integer, Curtain> curtains = new HashMap<>();//所有窗簾
public void printAll();//輸出所有裝置資訊
SourceMontor報表如下:
類圖如下:
分析
這次的程式模擬的電路系統中有許多存在關聯的類,例如調檔器可以改變電路中的電壓,開關可以決定電路中是否有電壓,互斥開關預設接引腳1和引腳2,窗簾在光照為0時預設開啟100%等隱藏條件,而且還有多個並聯電路串聯在一起的情況,因此需要格外注意。
採坑心得
需要注意的是本次迭代存在串聯電路中有串聯的情況,如:
#T1:[IN K2-1] [K2-2 D2-1] [D2-2 OUT]
T2:[IN K3-1] [K3-2 D1-1] [D1-2 OUT]
T3:[VCC K1-1] [K1-2 T1-IN] [T1-OUT T2-IN] [T2-OUT GND]
K1
K2
K3
end
同時還有另一個需要注意的點,這次輸出裝置資訊的順序改變了,比如同時有裝置1,11,2,如果按之前的排序應該按1,2,11的順序輸出,但這次是按1,11,2,的順序輸出,導致我在這個地方卡了好久。
改進建議
又於存在串聯電路中有串聯,多個並聯電路串聯的情況,因此在計算電阻時應該採用一些精妙的方法,比如先計算並聯電路中每一條支路的電阻,然後再計算串聯電路電阻,因為串聯電路中可能包含並聯電路,如果先算串聯再算並聯的話就會出錯。
家居強電電路模擬程式-2
設計
裝置類(Facility):所有裝置的父類
protected int id;//編號
protected String type;//裝置型別
protected double r = 0;//電阻
protected EnterPin pin1;//輸入引腳
protected OutPin pin2;//輸出引腳
protected boolean state = true;//裝置狀態
protected int maxI;//裝置最大電流
protected double I = 0;//透過裝置的電流
public void print();//輸出裝置資訊
裝置儲存類(Facility Factory):儲存所有裝置的資訊
public HashMap<Integer, Switch> switches = new HashMap<>();//所有開關
public HashMap<Integer, Gradegovernor> gradegovernors = new HashMap<>();//所有分檔調檔器
public HashMap<Integer, Continuousgovernor> continuousgovernors = new HashMap<>();//所有連續調檔器
public HashMap<Integer, Incandescentlight> incandescentlights = new HashMap<>();//所有白熾燈
public HashMap<Integer, Daylight> daylights = new HashMap<>();//所有日光燈
public HashMap<Integer, Ceilingfan> ceilingfans = new HashMap<>();//所有吊扇
public HashMap<Integer, Standfan> standfans = new HashMap<>();//所有落地扇
public ArrayList<Line> allLines = new ArrayList<>();//所有串聯電路
public ArrayList<Lines> lines = new ArrayList<>();//所有並聯電路
public HashMap<Integer, ExclusiveSwitch> exclusiveSwitches = new HashMap<>();//所有互斥開關
public HashMap<Integer, Curtain> curtains = new HashMap<>();//所有窗簾
public HashMap<Integer, Diode> diodes = new HashMap<>();//所有二極體
public void printAll();//輸出所有裝置資訊
並聯類(Lines):存放並聯電路資訊
public int number = 0;//並聯電路中通路的支路數量
ArrayList<Line> lines = new ArrayList<>();//並聯電路中的支路
引腳類(Pin):存放引腳的資訊
protected double v = 0;//電壓預設為0
protected int id;//引腳的編號
public String type;/8引腳裝置所屬的型別
開關類(Switch):存放開關的資訊
private int id;//開關的編號
public Pin pin1;//開關的引腳
public Pin pin2;//開關的引腳
private boolean state;//開關狀態
public void print()//輸出資訊
調檔器(Governor):存放調檔器的資訊
protected int id;//調檔器的編號
public EnterPin pin1;//輸入引腳
public OutPin pin2;//輸出引腳
public void print();//輸出資訊
分檔調檔器(Governor):存放分檔調檔器的資訊
protected int id;//調檔器的編號
public EnterPin pin1;//輸入引腳
public OutPin pin2;//輸出引腳
private double[] grade = {0, 0.3, 0.6, 0.9};//分檔調檔器的檔位
private int gear;
public void print();//輸出資訊
連續調檔器(Governor):存放連續調檔器的資訊
protected int id;//調檔器的編號
public EnterPin pin1;//輸入引腳
public OutPin pin2;//輸出引腳
private double grade;//調檔器的檔位
public void print();//輸出資訊
燈類(Light):存放燈的資訊
protected int id;//燈的編號
public EnterPin pin1;//輸入引腳
public OutPin pin2;//輸出引腳
public void print();//輸出資訊
風扇類(Fan):存放風扇的資訊
protected int id;//風扇的編號
public EnterPin pin1;/輸入引腳
public OutPin pin2;//輸出引腳
public void print();//輸出資訊
匹配類(Matching):對輸入的資訊進行處理
public void match()//對輸入的資訊進行處理
方法類(Method):對資訊進行處理並輸出
public static void electrify();//計算每一個裝置的電壓
public static void print();//將裝置資訊按順序進行輸出
SourceMontor報表如下:
類圖如下:
分析
這次迭代中要考慮並聯電路中包含並聯電路的情況,即構成並聯電路的串聯電路可以包含別的並聯電路。比如可能存在#M3:[M1 M2]的情況,同時由於互斥開關有三個引腳,因此在計算電壓時需要特殊考慮。
採坑心得
這一次迭代的幅度太大,有許多地方需要大改,比如之前幾次迭代中引腳的存在感很低,因此有些地方並沒有使用引腳,而這次根據題目要求必須使用引腳來計算電壓,同時因為存在並聯電路中包含並聯電路的無限套娃情況,在計算電阻時也需要更改方法,比如使用遞迴的方法計算電阻。
改進建議
由於這次迭代太難,導致我這次並沒有拿到滿分,因此只能給出有限的建議。我這次迭代1中是透過引腳來傳輸電壓,但由於互斥開關的存在,導致互斥開關至少有一個引腳被計算兩次,最終結果出錯,因此需要考慮如何解決這一問題,我是透過在互斥開關類中設定一個變數,儲存每個引腳的遍歷資訊來實現對引腳是否計算的判斷,同時由於存在大量的裝置,而且在每個環節幾乎都要呼叫,因此可以將所有裝置儲存到一個容器中,每次傳參時只需要傳入容器,不需要之前一大行的傳入,還可以儘可能多地將匹配,處理,輸出等方法分開以降低耦合度。
總結
透過這兩次作業,我對Hash Map的運用更加熟練,對於HashMap中的各種方法都有了更深的瞭解,並且可以將這些方法熟練運用到我的設計中。
同時,我對Java物件導向特點的理解更加深刻,在類的設計方面獲得巨大的提升,而且學會去分析類與類之間的關係,之後再透過題目資訊來分析如何實現需求,同時我會將功能模組化、封裝成類以提高程式碼的可讀性和可維護性。
本次Java作業讓我收穫頗豐,不僅加深了對Java程式語言的理解,還提高了實際程式設計能力。在未來的學習中,我將繼續深入學習Java程式語言及其相關技術,不斷提高自己的程式設計能力和解決問題的能力,保持學習的熱情和動力。