公司差點因為代碼寫得差把我直接給開掉
1.為什么需要我們重構(gòu)
- 重構(gòu)可以提高我們在寫作編碼時候的速度
- 重構(gòu)可以讓代碼更加的容易理解,方便其他人接手的時候,能夠快速的上手
- 重構(gòu)可以找出我們代碼里面隱藏的一些不易察覺的Bug,進而在之后的運行的過程中,能減少很多不必要的麻煩。
而在《重構(gòu):改善既有代碼的設(shè)計》說重構(gòu)的目的:讓軟件更加的容易理解和修改,而與之前的形成對比的是性能方面的優(yōu)化,不改變組件的行為,改變內(nèi)部結(jié)構(gòu),而重構(gòu)之后的軟件功能還是一如既往。
而阿粉是親身經(jīng)歷過有些人的代碼,咱們先不說這個功能實現(xiàn)的好壞,至少你必要的方法上面能不能寫點注釋,比如說實現(xiàn)某些功能的時候,你可以在方法的實現(xiàn)上面寫上,用于此處教師信息的導(dǎo)入,完成教師信息的分類別導(dǎo)入和基礎(chǔ)查詢,可能你在中間做了很多業(yè)務(wù)上的操作,不用像剛剛走上工作崗位的朋友一樣,每個方法上面都寫上注釋,但是必有的注釋還是要有的把,阿粉之前接手的一個項目,從頭到尾除了在配置文件里面寫了注釋,估計還是百度的時候?qū)懭肱渲玫臅r候加上去的注釋,一個注釋沒有,看的阿粉那叫一個崩潰。
2.都有哪些代碼需要重構(gòu)
2.1 重復(fù)代碼
最簡單的一個重構(gòu)的代碼,阿粉給大家放上一個片段,假如說我們有一個注冊和一個登陸的,
- @RequestMapping("regist")
- public Map<String,Object> registUser(HttpServletRequest request, HttpServletResponse response,String userName,String passWord){
- Map<String, Object> map = new HashMap<>();
- //校驗驗證碼是否正確
- if(PropUtils.checkCode(request.getParameter("Code"))){
- //如果校驗成功
- map.put("state",0);
- map.put("msg","驗證碼正確");
- }else{
- map.put("state",1);
- map.put("msg","驗證碼錯誤");
- }
- //此處保存帳號密碼
- return map;
- }
大家可以看一下上面的代碼,是不是很多地方我們可以直接把這些代碼進行封裝,畢竟你學Java的,你不會封裝方法的話,你豈不是就不是一個正兒八級的合格程序員了。
于是我們把這個代碼抽取出來,就組成一個方法,也可以使用IDEA的快捷鍵,Extract Method 這樣把我們重復(fù)的代碼提取出來,當我們在使用這段代碼的時候,我們就能夠把這些內(nèi)容直接調(diào)用,不用在直接拿過來復(fù)制粘貼,然后把代碼重新組合啥的,直接就可以把這個抽取出來的方法進行調(diào)用,實現(xiàn)我們的功能即可。
而上面就單獨說這個驗證這個驗證碼正確性這塊的內(nèi)容,我們在注冊的時候,有時候會需要這個驗證,在我們登錄的時候有時候也會需要這個,那么都是同樣的驗證,你這就相當于寫了兩次,如果說你不做抽取,那你的里面就出現(xiàn)了最簡單的這種代碼冗余。那我們這時候是不是就可以通過Extract Method把代碼抽取成一個方法,封裝起來,當我們需要這段代碼的時候,我們把這個參數(shù)傳遞過去,返回我們想要的數(shù)據(jù)就可以了,不是么?
2.2 巨長的參數(shù)
為什么阿粉要把這個放在第二個呢,因為這個也是大家有時候在寫代碼的時候最容易出現(xiàn)的問題,有很多剛剛初入公司的年輕人來說,那傳遞的參數(shù),那叫一個恐怖,一行兩行都不能滿足,比如說:
- HttpServletRequest request, int page, int limit, HttpServletResponse response,String oauthuser, String cupboardId, String boxId, String upboxuser,String sex,int age
大家看看這個,如果說你在寫完之后,生成注釋的話,這樣在注釋上面還能知道這個方法里面的參數(shù)是什么,規(guī)范一點的話,那也能知道,但是你如果起個亂七八糟的名稱,還這么這么多的參數(shù),誰看到了不是瘋狂想diss你。
而我們能怎么處理呢?這時候你是不是把對象忘記了,此對象非彼對象,而有了對象,我們就沒必要把我們函數(shù)需要的東西用多個參數(shù)傳遞了,我們只需要傳遞給他足夠的,讓函數(shù)能夠從中獲取自己需要的東西這樣就完全OK了,大家在這塊內(nèi)容也是經(jīng)常使用的。
比如我們大家在使用 Mybatis 的時候我們在resultType 里面是不是很多時候都會選擇傳遞一個對象回去,而如果沒有對象的時候,你去傳遞List
所以說,如果你的參數(shù)過長的時候,那么你就應(yīng)該需要考慮是不是要進行一下優(yōu)化了。
2.3 注釋太多,代碼很low
阿粉說這個的意思是這個樣子的,大家有沒有發(fā)現(xiàn),有時候,你看到注釋的時候,滿心歡喜的,感覺就是上一個哥們很給力呀,這注釋寫的明明白白的,但是看到下面的代碼的時候,就有了一種想要“一起去爬山”的心情,而我們在寫注釋的時候需要注意什么?
- 注釋形式統(tǒng)一,也就是我們的注釋盡量都是寫的一致,文檔注釋就是文檔注釋,語句注釋就是語句注釋,配置注釋就是配置注釋。
- 注釋一定簡明扼要,內(nèi)容簡單直白,是什么就是什么
- 注釋的數(shù)量,注釋必不可少,但也不應(yīng)過多,在實際的代碼規(guī)范中,要求注釋占程序代碼的比例達到20%左右。注釋是對代碼的“提示”,而不是文檔。
2.4 非常長的函數(shù)
話說阿粉在看到這個過長函數(shù)的時候,并沒有什么感覺,為什么函數(shù)過程不太好呢,阿粉把《重構(gòu):改善既有代碼的設(shè)計》中的第三章硬生生的看了好幾遍,書中大致內(nèi)容如下:
擁有短函數(shù)的對象會活的比較好,比較長. 不熟悉面向?qū)ο蟮娜?常常覺得對象程序中只有無窮無盡的委托,根本沒有進行任何計算. 和此類程序共同生活數(shù)年之后,你才會知道, 這些小小函數(shù)有多大價值. "間接層"所能帶來的全部利益- 解釋能力,共享能力,選擇能力.這都是由小型函數(shù)支持的.
這段話是出自書中的,那么這是個什么意思呢?其實說白了,就是,你的一個方法里面,寫了太多太多的邏輯,阿粉因為公司代碼涉密的關(guān)系,不能給大家截圖,而這里所說的就是,你在方法里面一個方法寫了1000多行的代碼。
真的有這么復(fù)雜的么,說實話,不排除這種可能性,畢竟程序是多變的,但是你是不是需要自己想一下,如果你寫了一個方法,方法里面處理了一大堆邏輯,然后滑輪使勁好幾下,一個方法沒結(jié)束,那么對接下來的維護人員,就不單單說維護人員了,就是你自己三個月之后來看自己寫的代碼,你確定你能維護好么?
而我們需要怎么做?
把邏輯整理,分解為不同的小函數(shù)(小方法)。提高可讀性,這樣,我們在之后的代碼維護也好維護,處理也好處理,不是么?
3.如何寫出優(yōu)雅的代碼
- 可讀性高
- 邏輯清晰
- 高內(nèi)聚,低耦合
- 學會應(yīng)用你所學的封裝,繼承,多態(tài)
- 已測試
到這里,阿粉希望大家能夠?qū)懗鲎銐騼?yōu)雅的代碼,不會像阿粉一樣,因為把代碼寫的稀碎,最終導(dǎo)致自己差點被公司開了。