政務雲參考技術架構行業優勢總體架構 政務雲平臺技術框架圖,由機房環境、基礎設施層、支撐軟體層及業務應用層組成,在運維、安全和運營體系的保障下,為政務雲使用單位提供統一服務支撐。功能架構標準雙區隔離 參照國家電子政務規範,打造符合標準的雙區隔離的政務雲平臺,互聯網區承載對公服務業務,政務外網區承載各單 ...
目錄
(1)前言
- `
- 第四次題目集主要是對答題判斷程式3的進一步改進,增加了對題目類的拆分,需要使用繼承的方式來實現各個種類的題目之間的聯繫,但是難度不是很大,只需要對答題程式3稍作修改,區別各個Question的內部實現,既多選與填空的判題方法等,還是很好修改的。此外還有兩個有關迭代的小題目,不是很難但是讓我瞭解了對toString方法的使用,這些都對後續的題目具有啟發作用,是從答題判斷程式到家庭電路系統的過度,能夠讓我們更能適應新題面的到來。
- 第五次題目集揭開了全新題面的大幕,面對智能家居的到來,我們也需要適應新潮流,針對家庭電路的控制進行模擬,本次主要進行了抽象類的實際使用,將電路中所有的電路設備進行抽象,所有的共同屬性都歸為一個大類,儲存了各種狀態和方法,在之後進行繼承與調用。只要確定好了方向,對於各個類的定義就自然會成型,測試點不難,很容易就能過,因為是第一次迭代,不用考慮得太多,只要能夠實現大致的功能就夠了,但是一定要在開始就確定好方向,不然很容易跌進思維陷阱。
- 第六次題目集對第一次的家庭電路系統進行了第一次修改,增加了串聯和並聯類,從只有一條簡單串聯電路更新到了存在多條串聯和並聯電路,並使並聯類關聯到串聯類,並聯多條單獨的串聯類,類間關係更加複雜,電壓的計算更加多變。
(2)設計與分析
`
第四次作業(答題判題程式-4)
新增多選和填空類,並將所有接收題目信息的方法全部移入Submission類中,類間關係更新為如下
新增多選類
按題目要求,增加多選類,主要繼承和重寫了題目類的判題方法,具體實現為:
for迴圈遍歷所有提交的答案,如果有與題目中某一個正確答案相同的選項,則設標誌flag為true
,如果遍歷結束flag仍為false
則證明所有答案都不符合,函數返回值0
,代表所有選項都不匹配,答案錯誤。在遍歷結束後,判斷提交答案的數組長度是否小於正確答案的數組長度,如果為真,則證明提交的答案不全,函數返回2
,代表半對。如果為假,則提交答案長度正好符合正確答案長度,且全部正確,即答案完全正確,函數返回1
新增填空類
按題目要求,增加填空類,主要繼承和重寫了題目類的判題方法,具體實現如下:
public int check(String fillAns)
{
if(fillAns.matches("\\s*"))return 0;//無答案判錯,與測試點無關
if(this.fillAns.matches(".*"+fillAns.trim()+".*"))
{
if(this.fillAns.equals(fillAns.trim()))
{
return 1;
}
return 2;
}
else return 0;
}
如果提交答案存在於正確答案中,則繼續判斷是否完全相同,相同則函數返回1
,代表答案完全正確,否則返回2
,代表部分正確,再否則則返回0
,代表答案錯誤。
第五次作業(家居強電電路模擬程式-1)
本次作業為第一次家庭電路的模擬,是一次全新項目的開始,題目要求模擬計算家庭220V電路下的設備電壓,實現各種電路設備之間的串並聯聯繫,可設置控制設備和受控設備兩種設備,使它們都繼承自電路設備類。類間關係設計如下:
Element類
根據題目要求,設計所有電路設備的父類如下:
abstract class Element implements Comparable<Element>
{
int id;
String inPin;
String outPin;
Boolean inUsed;
Boolean outUsed;
double inVolt;
double outVolt;
public abstract String getInPin();
public abstract String getOutPin();
public abstract Boolean getInUsed();
public abstract Boolean getOutUsed();
public abstract void setInPin(String inPin);
public abstract void setOutPin(String outPin);
public abstract char getType();
}
類中包含輸入引腳和輸出引腳,儲存另一個電路設備的引腳信息,在之後根據連接信息查找和搜索。並儲存了每個引腳的電壓,以便計算每個電路設備的電壓信息。
Element
類中包含抽象方法getType()
,在排序方法compareTo()
中調用,可以根據給定的順序排序所有Element的實例,具體實現如下:
public int compareTo(Element o)
{
String order = "KFLRBD";
if(getType()==o.getType())
return id-o.id;
return order.indexOf(getType())-order.indexOf(o.getType());
}
根據下標索引相減,可以大量減少排序方法的代碼塊,使用父類的抽象方法,能夠極大縮減函數復用帶來的不必要重覆。還可以根據給定順序排序,即使順序更改,只需要修改一處便可適應新排序。
與getType()
相似,Element
類中還包含toString()
方法,子類定義時,便重寫該方法,使得最後輸出時只需要短短一個for迴圈遍歷輸出,直接使用System.out.println(e);
即可輸出。
控制設備
開關#
public void changeState()
{
state ^= 1;
}
最簡單的控制設備,只有0和1兩種狀態,在切換狀態時可以使用異或運算簡化方法體。
分檔調速器#
比開關多兩個狀態,設有position
代表檔位(0~3),因為檔位連續,可用數組存儲每個檔位的調速數據,設立私有數據域private final double[] gradeTimes = {0,0.3f,0.6f,0.9f};
,在每次調速之後,用檔位對應下標,提取數據域中對應檔位的值,更新調速數據。
受控設備
白熾燈#
根據題目要求,白熾燈的亮度隨電壓差呈線性變化,可求出方程式為L = 50 + (V-10) / 1.4
,且電壓超過220和低於0時電壓不再變化,可寫出獲取亮度的方法如下:
public double getLighting()
{
double volt = getAbsVolt();
if(volt<=9)return 0;
else if(volt>=220)return 200;
else return 50 + (volt-10) / 1.4;
}
日光燈#
根據題意,電壓不為0時亮度恆為180,否則亮度為0。獲取電壓的方法可簡化為一個三目運算符volt == 0 ? 0 : 180
弔扇#
與白熾燈相似,弔扇的轉速與電壓差呈正比,可寫出獲取轉速的方法如下:
public double getSpeed()
{
double volt = getAbsVolt();
if(volt<80)return 0;
else if(volt>150)return 360;
else return 80 + 4.0 * (volt-80);
}
計算電壓(家庭電路類)
最初設計時,考慮到題目給出各個引腳的數據,所以我在Element
類中儲存了引腳的數據,記錄下了各個引腳通向的另一個引腳,於是在計算電壓的部分也利用了這部分數據,根據引腳的連通情況去進行搜索,每搜索到一個電器的同時去計算它的電壓情況,計算好電壓後,各個電器會在最後輸出階段自動調用已經寫好的方法,計算出需要輸出的數據。
可是如何去遍歷搜索卻成為了一個難題,在一開始我便想得太複雜了,想著儲存了引腳的數據,就一定要用上,可是越往後做越發現,引腳的數據在這次迭代中根本用不到,其實刪除這部分數據的輸入捕獲,也能夠做到全對,可是考慮到之後可能會用,便仍接著遍歷搜索的思路去寫了。
在計算電壓之前,先遍歷找出VCC
引腳接在了哪個用電器上,並從該用電器作為出發點開始搜索計算。給出VCC
所在的引腳和接入的電路設備,如果引腳為1,則將2引腳電壓更新,並將該引腳和與它連接的電路設備加入到隊列q中,然後進行下一次遍歷,反之依然。如果隊列q中沒有電路設備,則迴圈結束,如此搜索完一遍,便可以將所有引腳的電壓都計算出來,在得到所有引腳的電壓之後,便可以用電壓差計算出每個設備的電壓。由於我寫的太過繁瑣,就不展示出來了。大家可以自己去嘗試寫一下。
第六次作業(家居強電電路模擬程式-2)
Element類
看到本次題面,我發現引腳還是沒有被用上,於是我一怒之下怒了一下,把引腳直接給刪除了(),Element類被修改為如下:
abstract class Element implements Comparable<Element>
{
int id;
double voltage;
double resistance;//電阻
final double EPS = 1e-10;
final double INF = Double.POSITIVE_INFINITY;//1.78e+308
abstract boolean canGo(Element e);
public void updateVolt(double wholeResistance,double wholeVolt)
{
voltage = resistance * wholeVolt / wholeResistance;
}
public double getVolt()
{
return Math.abs(voltage);
}
public abstract char getType();
@Override
public int compareTo(Element o)
{
String order = "KFLBRDAHS";
if(getType()==o.getType())
return id-o.id;
return order.indexOf(getType())-order.indexOf(o.getType());
}
}
由於本次迭代考慮了電阻,於是我將電阻的數據直接存放在Element
類中,方便直接調用。考慮到電路斷路電阻為無窮大,我又在類中放了一個final
類型的數據INF
代表無窮大,在電路斷路時方便直接設置,並且該無窮大直接使用Double
類中的無窮大,意為真正的無窮大。既然Double類中已經實現好了,自然要偷這個懶。並且類中還存放了另一個final
類型的數據EPS
,電壓電阻等數據為Double
類型,計算時需要考慮精度問題,需要時可方便直接調用。
在經過幾輪思考之後,Element
中還新增了一個canGo
的抽象方法,返回該電路設備是否能讓電流通過,對於所有的開關,canGo
根據閉合狀態返回是否可通過;對於所有用電器,直接返回true
,即使在之後要考慮電壓過大用電器會燒斷,也可以直接在該方法中修改返回值;對於所有串聯電路,只要電路中有一個元件的canGo
方法返回了false
,便直接返回false
。對於並聯電路也同樣可以這樣思考,這便是根據實際情況,使用遞歸運算簡化了代碼的複雜度。
Light類
抽象出所有燈的父類Light
,由於所有燈都有亮度的數據,並且輸出時結構相似,於是在Light
類中添加抽象方法getLighting()
,並將所有燈的輸出方法放在Light
類中,如此一來,便又一次降低了代碼量,增加了方法的復用度。
abstract class Light extends Electric
{
public abstract double getLighting();
@Override
public String toString()
{
return "@"+getType()+id+":"+String.format("%.0f",Math.floor(getLighting()));
}
}
Fan類
與Light類似,本次添加了一種風扇,風扇種類便從1變為了2,所以可以抽象出Fan
類,同樣具有所有風扇類都有的轉速屬性,並且輸出結構類似,於是添加抽象方法getSpeed()
和toString()
方法
abstract class Fan extends Electric
{
public abstract double getSpeed();
@Override
public String toString()
{
return "@"+getType()+id+":"+String.format("%.0f",Math.floor(getSpeed()));
}
}
(3)採坑心得
由於考慮了引腳之間的連接,題目被我想得複雜化了,因此修改了很久都不對,太過複雜的連通關係總是把我繞進去,改卻總又改不對,最後還是要簡化,所以在一開始構思的時候不能想得太複雜,一切都要從簡,然後才去慢慢深入修改。
還有就是一定要通篇檢查代碼,不要自以為某一段沒有問題就不去檢查,因為家庭電路系統-1題面中要求到要對電路設備進行排序,而答案提交之後也順利通過了,所以在第二次迭代中我就沒去檢查這段代碼,以至於一直修改其他地方分數卻保持不變,直到最後才開始懷疑。
(4)改進建議
在之後的迭代中,我希望能夠引腳的部分重新加回來,但是不需要通過太複雜的代碼或是對代碼整體重新修改,就像是上面說的,不用一開始就想得複雜,而在之後通過打補丁的方式加入功能。也希望之後無論添加什麼功能,都能輕易修改好,隨後僅剩一點點的調試。
(5)總結
抽象是步入java大門的一把利器,不僅在家庭電路模擬中,也能用在各個場景中。面向抽象編程,不需要在一開始就將功能全部設想到,而是利用抽象的特性,一步步具象化,這樣不僅代碼清晰,每一步需要考慮的東西也減少了,將一次不能夠完成的功能分佈展開,能夠在讓自己在每一步迭代中清晰的知道自己在這一次要完成什麼,也能讓自己寫代碼的效率提高。
總的來說,這三次題目集又讓我學到了很多,希望之後的迭代不會超出我代碼的可變範圍。希望自己對代碼的掌控更加熟練。