本文摘自華為云社區(qū),作者:Jet Ding
“每天都會有更多的技術(shù)發(fā)生,每家公司都在互聯(lián)網(wǎng)上,每家公司都將成為一家科技公司。”O(jiān)KTA首席運營官兼聯(lián)合創(chuàng)始人Frederic Kerrest說道,因為他們必須找出使用該軟件的更好方法。軟件不僅成為了一個必需品,更成為了一個競爭優(yōu)勢。因為眾多公司圍繞軟件而競爭,軟件開發(fā)相關(guān)的事宜顯得越發(fā)重要。開發(fā)軟件的人——軟件工程師正顯得越發(fā)重要。
“對于知識,要求知若渴;對于自己,要虛懷若谷。”優(yōu)秀的軟件工程師一定是在軟件開發(fā)的道路上前行者。自學(xué)是其成長的一個重要手段,在自學(xué)的過程中,我們是可以通過考試的方式來收斂思緒,督促自己學(xué)習(xí),從而提高自己的基本素質(zhì)。誠然,原則和模式是軟件工程質(zhì)量的基石。但技術(shù)是工具, 是為人服務(wù)的,而不是相反的。我們不能為了迎合某種技術(shù)而束手束腳,讓自己特別難受。與此同時,要讓自己的能力發(fā)揮到極致,良好的心境是必須要有的,因為軟件工程中的一個核心因素是人的因素。
誠然,在軟件開發(fā)過程中,我們不僅要將自身內(nèi)功修煉好,更應(yīng)該 “用產(chǎn)品說話”。那么,在這個過程中,我們該如何保證開發(fā)的質(zhì)量呢?在開發(fā)的過程中如何專注于自己擅長的事情呢?在本文中,我們將探討軟件開發(fā)過程中關(guān)于角色、重構(gòu)和質(zhì)量的問題。
角色
我們經(jīng)常提一句話:革命工作只有分工不同,沒有高低貴賤之分。這里的分工其實就是角色的劃分。角色劃分是為了讓個體承擔(dān)的工作量最小化,從而可以把我們從繁文縟節(jié)中解放出來,專注于自己擅長的事情。那么,在軟件工程當(dāng)中,這樣的理念應(yīng)該如何貫徹呢?
軟件工作里面的臟活兒、累活兒一般是指技術(shù)老舊而不得不維護的一些工作。還有一些重復(fù)性強的工作也被稱為臟活兒、累活兒。
對于這種活兒,一般工程師都想推脫掉。主要原因是認為做這類活兒技術(shù)提高的空間很小,再加上技術(shù)陳舊,這些技巧學(xué)會了以后也用不上,同時也比較枯燥。
這類工作的工程師一般是指派的。需要對相關(guān)的工程師進行一些必要的技術(shù)培訓(xùn)或者直接招收懂得相關(guān)技術(shù)的工程師加入工作。
效率和價值主要體現(xiàn)在幫助客戶解決現(xiàn)有軟件系統(tǒng)中的問題,或者添加新的功能。客戶可能很少愿意購買一套嶄新的系統(tǒng),因為價格相對比較高,所以他們寧愿少花點錢去做些修修補補的工作,能夠解決燃眉之急就可以了。
運維工作的價值是把已經(jīng)開發(fā)出來的組件和系統(tǒng)集成起來統(tǒng)一的工作。是推出面向用戶的軟件系統(tǒng)產(chǎn)品的重要一步。我不認為是邊角料的活兒。
運維相關(guān)的工作越簡潔越清晰越好。這部分相關(guān)的文檔一般是read me markdown的形式存放在軟件系統(tǒng)的repo中。通過查看這些文檔,應(yīng)該可以自行部署整套系統(tǒng)。
系統(tǒng)部署一般會分幾種類別,開發(fā)模式,qa模式,staging模式和生產(chǎn)模式。 業(yè)界對于軟件開發(fā)過程中的角色有不同的理解和看法。筆者觀點如下:
1.項目產(chǎn)品經(jīng)理負責(zé)業(yè)務(wù)需求的處理,負責(zé)跟客戶與開發(fā)團隊打交道。
2.項目開發(fā)組長一定是全棧,需要統(tǒng)籌規(guī)劃,與項目經(jīng)理一起探討需求分析,與開發(fā)組成員一起探討開發(fā)設(shè)計,任務(wù)分配與開發(fā)實現(xiàn)。
3.前端工程師負責(zé)網(wǎng)絡(luò)頁面程序開發(fā),手機端應(yīng)用開發(fā),桌面端應(yīng)用開發(fā)等等。
4.后端工程師負責(zé)API設(shè)計與開發(fā), 數(shù)據(jù)分析處理與消息推送。
5.運維工程師負責(zé)部署環(huán)境的搭建與看護。
6.針對具體的業(yè)務(wù)需求,還會有更細分的角色類別,比如說大數(shù)據(jù)工程師,算法工程師,AI工程師,機器學(xué)習(xí)工程,深度學(xué)習(xí)工程師, 中間件工程師。
7.測試工程師負責(zé)系統(tǒng)集成后的業(yè)務(wù)需求案例測試。這一部分的輸入跟開發(fā)團隊的輸入是一樣的,都是用戶的需求。輸出則是需求案例對應(yīng)的測試報告。而開發(fā)團隊的輸出就是整個軟件系統(tǒng)。
重構(gòu)
為什么我們需要對代碼和設(shè)計進行重構(gòu)?主要是因為我們發(fā)現(xiàn)了更好的做法,如效率更高,更容易維護等等。簡單的代碼重構(gòu)我們都比較熟悉,比如說你通過工具就可以做一些整理。
一般來說,重構(gòu)是為了解決復(fù)雜度的問題。
現(xiàn)在比較頭疼的一個話題就是對老產(chǎn)品的重構(gòu),一些老產(chǎn)品涉及到上千萬行,上億行的代碼。 關(guān)于老產(chǎn)品整改的問題。如果只是縫縫補補的話,可能起不到化繁為簡的目的。其實做類似這種工作的話,有一個比較可行的方案。就是把現(xiàn)有的產(chǎn)品當(dāng)做一個成型系統(tǒng)也就是現(xiàn)有運行的產(chǎn)品,不要做大的改動,頂多就是修改bug。
然后以這些成型的系統(tǒng)為基準,去寫新的系統(tǒng)。相當(dāng)于參照一個大的白盒就寫一個小的白盒,這樣新的小的白盒質(zhì)量上肯定比大的白盒性能上要有優(yōu)勢。這樣子按部就班去做的話,就會比較靠譜。 有朋友會說上面的做法是重寫,字面意義上沒錯的。
實際上不矛盾。區(qū)別就是重構(gòu)的方式應(yīng)該從下往上還是從上往下。比如說我們現(xiàn)在大部分的重構(gòu)都理解為從下往上來做。也就是感覺這個文件里頭有壞代碼的味道,然后就改這個文件,這樣做是沒有問題的。前提是這項工作的上下文比較單純,無技術(shù)債務(wù)。
很多情況不是如此幸運的,比如現(xiàn)在有些人遇到的問題,就是發(fā)現(xiàn)上下文不是很清晰,這個代碼為什么要這么寫?為什么一個文件有1萬行或者3萬行,這個來龍去脈不是很清楚。
這個時候可能就需要從整個子模塊來進行一個自上而下的分析。梳理出這個子模塊的功能需求是怎樣的,需要有多少個公共接口?內(nèi)部公共接口的實現(xiàn)方式是不是應(yīng)該像目前這樣的?
一個文件能夠?qū)懗?萬行或者3萬行,肯定是有一定歷史原因的,絕大程度是由于全局把握的編程能力不夠造成的。像這種情況,如果從這個文件本身去做重構(gòu)的話,難度非常之大,但是如果從上往下,從模塊的整個設(shè)計角度來做重構(gòu)的話,可能就容易一些。
對于這樣的龐然大物,最好的辦法就是分而治之。首先要確定系統(tǒng)的功能邏輯點,針對這些邏輯點,要編排好對應(yīng)的檢測點,也就是說等我們完成了重構(gòu)以后,我們得確保我們的重構(gòu)是沒有問題的,這些檢測點就是做這個的,我們可以理解成集成類的測試。
這些集成類的測試一定要確保可以在當(dāng)前未重構(gòu)之前的系統(tǒng)上正常運行。
有了這個設(shè)施以后,我們就可以開展我們的重構(gòu)工作。重構(gòu)的方法有很多,比如采用比較好的工具,函數(shù)和變量的命名改變,調(diào)用方式的改變等等。這些是在現(xiàn)有代碼的基礎(chǔ)上進行的重構(gòu)。這里我們重點說一下重寫的方式來實現(xiàn)重構(gòu)。所謂重寫呢,就是另外開辟一套代碼底座。甚至可以選用不同的編程語言。
這種情況下重構(gòu)首先要重用已有的業(yè)務(wù)邏輯,實現(xiàn)針對業(yè)務(wù)邏輯集成測試100%的通過率。
具體不管采用哪種方式都要一個模塊一個模塊的進行推進。驗證完成一個是一個,千萬不能急于求成,試圖一次性的把某些問題搞定。如果出現(xiàn)很多次失敗,有可能會消磨掉你的自信心。所以一定要一點一點的往前推進,始終是在進步當(dāng)中。采用了這種方式以后,不管當(dāng)前的系統(tǒng)有多么的龐大,你只要堅持做下去,就一定能夠把重構(gòu)工作徹底完成。 這個時候需要做的具體步驟可以參考如下:
1. 根據(jù)功能需求定義公共接口。
2. 根據(jù)公共接口寫出測試案例代碼。
3. 這個時候可以按照測試驅(qū)動開發(fā)的理念去填充代碼。
4. 代碼可以從現(xiàn)有的代碼中抽取出來。
5. 在抽取的過程中進行整理重構(gòu)。
這樣,這個子模塊完成以后,就可以嘗試去替代現(xiàn)有的子模塊,看看能不能在整個系統(tǒng)中安全的運行。
對于整個系統(tǒng)來說,我們又可以分成很多個子模塊。然后又可以對各個子模塊各個擊破,最終完成對整個系統(tǒng)的重構(gòu)。
如果一開始對整個系統(tǒng)進行重構(gòu)的話,也是可以從自上而下的角度來看的。比如說開始的時候先把所有的子模塊看成一些占位符,假定他們已經(jīng)完成他們的接口了。那對于整個系統(tǒng)來說,它本身就是一個子模塊,屬于提綱挈領(lǐng)的那個模塊。
這個過程,從字面意義上可以理解成重寫,實際上,它也是一個重構(gòu)的過程,因為我們肯定會重用這個系統(tǒng)本身的一些現(xiàn)有代碼和現(xiàn)有的邏輯。
上面我們是假定系統(tǒng)在已經(jīng)完成的情況下進行的重構(gòu),其實重構(gòu)可以貫穿于軟件開發(fā)的始終。軟件開發(fā)的首要目標是實現(xiàn)業(yè)務(wù)邏輯,能夠解決客戶的問題。這個目標實現(xiàn)以后,我們就要追求代碼的干凈度,復(fù)雜度能夠降到最小,當(dāng)前的技術(shù)能夠用到最先進。所以只要有機會,我們都應(yīng)該對代碼和設(shè)計進行重構(gòu)。
質(zhì)量
質(zhì)量直接關(guān)系到客戶是否對我們的產(chǎn)品滿意。那我們應(yīng)該如何保證軟件開發(fā)的質(zhì)量呢?
要遵循整個開發(fā)團隊的共識才能保證質(zhì)量。共識是一個可大可小的術(shù)語,大到理想、哲學(xué)、人生觀;小到軟件設(shè)計原則,設(shè)計模式,代碼風(fēng)格。如果是打造一個團隊那就是長期的目標,共識一定要從大的方向上入手。如果僅僅為了開發(fā)一個項目,共識可以從具體的細節(jié)著手。 軟件質(zhì)量的保證,需要整個團隊形成共識,大家都遵循這個共識。這個共識體現(xiàn)在開發(fā)原則,設(shè)計模式和代碼上,具體表現(xiàn)在架構(gòu)代碼和模板代碼上,在項目最初的開發(fā)階段,開發(fā)速度一定要慢,就是為了經(jīng)過反復(fù)的推敲夯實,把代碼的共識部分建立起來。
風(fēng)格上的目標是,不管這個團隊有多少個人,寫出來的代碼,就像一個人的代碼一樣,風(fēng)格是一致的。
代碼的質(zhì)量也體現(xiàn)在復(fù)雜度上。復(fù)雜度的目標是,在目前的技術(shù)條件下,當(dāng)前的代碼的復(fù)雜度應(yīng)該為最低。
另一個軟件高質(zhì)量的重要指標是代碼的白盒可測性。測試的框架應(yīng)該在項目開始階段搭起來。等部分代碼成型的時候,逐步的添加必要的測試案例。測試案例的選取可以按照環(huán)形復(fù)雜度的計算方法來確定,也可以根據(jù)集成測試對應(yīng)的用戶需求來確定。
接下來進一步細說一下軟件開發(fā)中的測試。與代碼相關(guān)的測試,一般有單元測試,集成測試和系統(tǒng)級的測試。
單元測試,一般被認為非常繁瑣。單元測試的繁瑣主要體現(xiàn)在測試案例的選取上, 如果使用全覆蓋方式來選取測試案例的話,會產(chǎn)生大量的測試代碼,以后維護起來也是一個負擔(dān)。如果采用環(huán)形復(fù)雜度來選取測試案例的話,會產(chǎn)生適量的測試代碼,但是環(huán)形復(fù)雜度的計算也是一個很大的時間開銷。
集成測試跟客戶的實際業(yè)務(wù)需求相關(guān)。在這個過程中需要理清接口的輸入與輸出,以及運行路徑,然后據(jù)此來設(shè)計測試案例,寫出測試案例代碼。 開發(fā)人員一般不會拒絕寫集成測試。因為她帶來的好處是實實在在的,會極大的提高你的開發(fā)效率和調(diào)試效率。尤其是對于無界面的程序接口尤為重要。
系統(tǒng)級測試是大系統(tǒng)中子系統(tǒng)之間的集成測試。這個主要包含兩個方面:一個方面是有界面的自動化測試,通過這樣的測試架構(gòu)來模擬人類用戶的使用過程,同時增加一些隨機性的行為,試圖能夠找出系統(tǒng)的一些漏洞。 另一種是無界面的測試,體現(xiàn)在多個服務(wù)系統(tǒng)之間的調(diào)用上或者類似瀏覽器自動化框架的使用上。
一套完整的測試系統(tǒng),可以幫助工程師提高開發(fā)效率,減少以后系統(tǒng)維護和重構(gòu)的成本。
從測試的緊迫性上來說,集成測試最為必要,系統(tǒng)間的測試有時候使用手工測試通過一些測試工具來代替。單元測試可以有很廣闊的討論空間,這部分要具體問題具體分析。 如果只是為了應(yīng)付檢查而寫測試代碼,是沒有意義的。如果測試代碼沒有起到應(yīng)有的價值,寫測試代碼也是沒有意義的。工程師是軟件高質(zhì)量的主要執(zhí)行者。項目組長,架構(gòu)師和開發(fā)經(jīng)理是軟件高質(zhì)量的護航者和守護者。所以不能放任讓工程師從下而上的去保證軟件質(zhì)量,這個要求對工程師來說過高了。
小結(jié)
最后提一下工程師文化和主人翁精神。對于工程師文化的內(nèi)涵,我認為包含如下幾點:
(1)工匠精神,對于所做的事情有著精雕細琢的熱忱。
(2)試錯文化,勇于嘗試,愿意做第一個吃螃蟹的人。
(3)自律,這個自律是指“吾日三省吾身”。不斷的自我糾錯反省提高。
對于主人翁精神,不管做什么工作,只要想充分發(fā)揮自己的能力,真正的做些事情,不管級別如何,薪水多寡,簡單地說,就是時刻把所做的事情當(dāng)作自己的事情來做。否則的話,時刻斤斤計較,我們做事情的時候就無法全力以赴。 如果抱有患得患失的心態(tài),我們的工作效率就會下降。久而久之,不僅賺不到想賺的“大錢”,也會阻礙自己能力和心境的提高,可謂是撿了芝麻,丟了西瓜。時間是寶貴的,真的不容浪費。 對于主人翁精神的一些具體表象很多,諸如:從來不說“這不是我的事”;做事情不為了短期利益而犧牲長期利益;等等。 通過本文,筆者梳理了一下從事軟件工作二十多年來的心得體會,希望能給大家?guī)硪恍┯幸饬x的啟示。
責(zé)任編輯:xj
原文標題:論軟件工程師的自我修養(yǎng):角色、重構(gòu)與質(zhì)量
文章出處:【微信公眾號:華為開發(fā)者社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
-
工程師
+關(guān)注
關(guān)注
59文章
1571瀏覽量
68614 -
軟件
+關(guān)注
關(guān)注
69文章
5007瀏覽量
87993
原文標題:論軟件工程師的自我修養(yǎng):角色、重構(gòu)與質(zhì)量
文章出處:【微信號:Huawei_Developer,微信公眾號:華為開發(fā)者社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論