OC代碼規范:
一、 好代碼的定義是優雅的使用各種設計模式,兼顧各種情況(異常或是正常),有效而且合理的使用優化算法。
1. 單頁代碼最好控制在800行以內,每個方法最好不要超過100行,過多建議對代碼進行重構
2. 相同的邏輯方法定義避免在多個地方出現,盡量將公用的類、方法抽取出來
3. 刪除未被使用的代碼,不要大片注釋未被使用的代碼,確定代碼不會使用,請及時刪除
4. 對其他項目中copy過來的代碼,根據具體需要更新代碼風格,及時刪除未被使用的代碼
5. 項目中所有Group或者文件名稱(圖片名字等),不要使用漢字命名,盡量使用英文命名,國內特有名詞可以使用拼音。
6. 項目中所有Group都需要在項目目錄中存在一個真實的目錄,Group中的文件與真實目錄中文件一一對應。
7. 請在項目中寫必要代碼的注釋
8. 請多使用 #pragma mark – Mark Name 對方法進行分組 。
9. 所有類名稱以項目工程開頭命名,如:“JS”(簡書)。針對不同視圖控制器,在末尾添加后綴,如: UIButton 后綴添加“Button”或大家皆知的簡寫,NSArray的變量命名為xxxArray等。
10. 類、方法、屬性等命名,做到見名知意,采用駝峰式命名規則。
11. 根據資源類型或者所屬業務邏輯對項目資源進行分組,使得整個項目結構清晰明了;整個項目保持一種代碼書寫風格。
12. 避免在程序中直接出現常數,使用超過一次的應以宏定義的形式來替代。常數的宏定義應與它實際使用時的類型相一致。如以3.0來定義浮點類型,用3表示整型。 常量的命名應當能夠表達出它的用途,并且用大寫字母表示。例如:#define PI 3.1415926
13. 當使用條件語句編碼時,不要嵌套if語句,多個返回語句也是OK。- (void)testMethod
{? if (![testSome boolValue]) {
// 不合適就返回,下面做處理
return;
}
//Do something import
}
- (void)testMethod
{ if (![testSome boolValue]) {
// 不合適就返回,下面做處理
return;
}
//Do something important
}
14. 當方法通過引用來返回一個錯誤參數,判斷返回值而不是錯誤變量。在成功的情況下,有些Apple的APIs記錄垃圾值(garbage values)到錯誤參數(如果non-NULL),那么判斷錯誤值會導致false負值和crash。
NSError *error;
if (![self trySomethingWithError:&error]) {
// Handle Error
}
NSError *error;if (![self trySomethingWithError:&error]) {??// Handle Error}
15. 當參數過長時,每個參數占用一行,以冒號對齊。如:
- (void)aboutFisrtNumber:(NSString *)oneStr
withNextNumber:(NSString *)twoStr
withLastNumber:(NSString *)threeStr{
// do something
}
- (void)aboutFisrtNumber:(NSString *)oneStr??????????withNextNumber:(NSString *)twoStr??????????withLastNumber:(NSString *)threeStr{// do something}
16. 一行很長的代碼應該分成兩行代碼,下一行用兩個空格隔開
self.productsRequest = [[JSProductsRequest alloc]
initWithProductIdentifiers:productIdentifiers];
self.productsRequest = [[JSProductsRequest alloc] ??initWithProductIdentifiers:productIdentifiers];
17. 刪除多余的空行,所有方法與方法之間空1行,所有代碼塊之間空1行。變量聲明后需要空1行,如果需要分類區別,各類別之間空1行。條件、循環,選擇語句,整個語句結束,需要空1行。最后一個括弧之前不空行。注釋與代碼之間不空行。
#pragma 與方法之間空1行
18. 每行代碼最多不得超過100個字。
19. 如果類聲明中包含多個protocol,每個protocol占用一行,縮進2個字符如:
@interface BootViewController : UITableViewController
UITableViewDelegate,
UITableViewDataSource,
UITextFieldDelegate,
UITextViewDelegate
>{
// code
}
20. 圖片命名:采用單詞全拼,或者大家公認無岐義的縮寫(比如:nav,bg,btn等);采用“模塊+功能”命名法,模塊分為公共模塊、私有模塊。公共模塊主要包括統一的背景,導航條,標簽,公共的按鈕背景,公共的默認圖等等;私有模塊主要根據app的業務;功能模塊劃分,比如用戶中心,消息中心等。建議背景圖采用以bg作前綴,按鈕背景采用btn作前綴。如:account_gray_qq@2x.png,addpic_icon_menu_disable@2x.png等。
二、? 架構是一個約定,一個規則,一個大家都懂得遵守的共識;最終體現是一個軟件,是模塊化,簡潔,可維護,可任意替換,人性化設計,可以把它全部打碎了重新從一個模型自由的再去組裝成另一個模型。是高內聚,低耦合,既可以作為一個完整的可交付模塊,也可以“打碎”重組;需要考慮的是擴展性,安全和性能。
1、架構(Architecture)有兩個要素:
(1)它是一個軟件系統從整體到部分的最高層次的劃分。
(2)一個系統通常是由元件組成的,而這些元件如何形成、相互之間如何發生作用,則是關于這個系統本身結構的重要信息。
2、好的架構需要下面幾點:
(1)代碼整齊,分類明確,沒有common,沒有core
(2)不用文檔,或很少文檔,就能讓業務方上手
(3)思路和方法要統一,盡量不要多元
(4)沒有橫向依賴,萬不得已不出現跨層訪問
(5)對業務方該限制的地方有限制,該靈活的地方要給業務方創造靈活實現的條件
(6)易測試,易拓展
(7)保持一定量的超前性
(8)接口少,接口參數少
(9)高性能
3、架構師的第一職責是關注非功能性需求,就是對技術的全面掌控。包括:
(1)TCP/IP協議,
(2)加密解密,
(3)計算機原理(增補反碼),
(4)JPG碼,
(5)MPEG2-3協議,
(6)邏輯電子電路,
(7)計算機編譯器原理(堆、棧、隊列)
(8)、、、、、
一些底層的東西,才是技術的核心。
三、? 構建項目時:全局觀、高度的代碼審美能力、靈活使用各種設計模式一定都要貫穿其中,搞清楚業務邏輯,這決定了你的架構是否足夠易用。另外,傳的參數越少,耦合度相對而言就越小,你替換模塊或者升級模塊所花的的代價就越小。搞清楚業務之間的依賴關系,建立好模塊交流規范并設計模塊,關鍵在于建立一套統一的交流規范。推演預測一下未來可能的走向,必要時添加新的模塊,記錄更多的基礎數據以備未來之需。軟件是有生命的,多一點考慮便會多一分健壯。
*、在CMM(能力成熟度模型Capability Maturity Model的縮寫,是一種側重于軟件開發過程的管理及工程能力的提高與評估的開發模型)神話崩潰以后,敏捷開發逐漸引起了人們的關注,并被寄予厚望。
*、我們大部分人都學過瀑布開發模型,它是以文檔為驅動的。因為在瀑布的整個開發過程中,開發人員根據需求文檔進行開發,一切以文檔為依據。
3、敏捷開發(Agile Development)是一種以人(團隊)為核心、迭代、循序漸進的開發方法,是一種軟件開發的流程
敏捷開發指導我們用規定的環節去一步一步完成項目的開發;而這種開發方式的主要驅動核心是人,注重的是人與人之間,面對面的交流;它只寫有必要的文檔,或盡量少寫文檔;采用的是迭代式開發。
敏捷開發提倡將一個完整的軟件版本劃分為多個迭代,每個迭代實現不同的特性。重大的、優先級高的特性優先實現,風險高的特性優先實現。在項目的早期就將軟件的原型開發出來,并基于這個原型在后續的迭代不斷完善。
敏捷開發好處是:
(1)盡早編碼,
(2)盡早暴露項目的技術風險
(3)盡早使客戶見到可運行的軟件,并提出優化意見。
(4)可以分階段提早向不同的客戶交付可用的版本。
敏捷開發的二個特點:
(1)開放式辦公,包括測試人員也和開發人員一起辦公。
(2)充分溝通,基于Story Card的開發方式,
在每個迭代中,架構師負責將所有的特性分解成多個Story Card。
每個Story可以視為一個獨立的特性。
每個Story應該可以在最多1個星期內完成開發,交付提前測試(Pre-Test)。當一個迭代中的所有Story開發完畢以后,測試組再進行完整的測試。
在整個測試過程中(pre-test,test),基于Daily build,
測試組永遠都是每天從配置庫上取下最新編譯的版本進行測試,
開發人員也隨時修改測試人員提交的問題單,并合入配置庫。
團隊會在開放式辦公區域放置一塊白板,上面粘貼著所有的Story Card,按當前的開發狀態貼在4個區域中,分別是:未開發,開發中,預測試中,測試中。Story Card的開發人員和測試人員根據開發進度在Story Wall上移動Story Card,更新Story Card的狀態。這種方式可以對項目開發進度有一個非常直觀的了解。
(個人認為:Scrum簡單理解:就是這張圖;XP:就是適應隨時隨地變更的需求)
敏捷開發的具體方式:Scrum和XP(Extreme Programming:極限編程)
Scrum(迭代式增量軟件開發過程,通常用于敏捷軟件開發,偏重于過程)
Scrum能迫使你敏捷開發,迫使你在每個Sprint結束的時候把東西都實現、發布。它不會讓你做出目前用不到的多余的東西;
Scrum不允許你在實現東西上有任何所謂“正確方式”的奢侈行為。
Scrum整個開發過程由若干個短的迭代周期組成,一個短的迭代周期稱為一個Sprint,每個Sprint的建議長度是2到4周(互聯網產品研發可以使用1周的Sprint)。在Scrum中,使用Product Backlog來管理產品的需求,Product backlog是一個按照商業價值排序的需求列表,Scrum團隊總是先開發對客戶具有較高價值的需求。在Sprint中,Scrum團隊從產品Backlog中挑選最高優先級的需求進行開發。挑選的需求在Sprint計劃會議上經過討論、分析和估算得到相應的任務列表,我們稱它為Sprint backlog。在每個迭代結束時,Scrum團隊將遞交潛在可交付的產品增量。Scrum 采用迭代、增量的方法來優化可預見性并控制風險。
Scrum開發流程及三大角色
(1).我們首先需要確定一個Product Backlog(按優先順序排列的一個產品需求列表)
--->產品負責人(Product Owner)
主要負責確定產品的功能和達到要求的標準,指定軟件的發布日期和交付的內容,同時有權力接受或拒絕開發團隊的工作成果。
(2).Scrum Team根據Product Backlog列表,做工作量的預估和安排;
(3).有了Product Backlog列表,我們需要通過 Sprint Planning Meeting(Sprint計劃會議) 來從中挑選出一個Story作為本次迭代完成的目標,這個目標的時間周期是1~4個星期,然后把這個Story進行細化,形成一個Sprint Backlog;
(4).Sprint Backlog是由Scrum Team去完成的,每個成員根據Sprint Backlog再細化成更小的任務(細到每個任務的工作量在2天內能完成);
(5).在Scrum Team完成計劃會議上選出的Sprint Backlog過程中,需要進行 Daily Scrum Meeting(每日站立會議),每次會議控制在15分鐘左右,每個人都必須發言,并且要向所有成員當面匯報你昨天完成了什么,并且向所有成員承諾你今天要完成什么,同時遇到不能解決的問題也可以提出,每個人回答完成后,要走到黑板前更新自己的 Sprint burn down(Sprint燃盡圖);
(6).做到每日集成,也就是每天都要有一個可以成功編譯、并且可以演示的版本;很多人可能還沒有用過自動化的每日集成,其實TFS就有這個功能,它可以支持每次有成員進行簽入操作的時候,在服務器上自動獲取最新版本,然后在服務器中編譯,如果通過則馬上再執行單元測試代碼,如果也全部通過,則將該版本發布,這時一次正式的簽入操作才保存到TFS中,中間有任何失敗,都會用郵件通知項目管理人員;
(7).當一個Story完成,也就是Sprint Backlog被完成,也就表示一次Sprint完成,這時,我們要進行 Srpint Review Meeting(演示會議),也稱為評審會議,產品負責人和客戶都要參加(最好本公司老板也參加),每一個Scrum Team的成員都要向他們演示自己完成的軟件產品(這個會議非常重要,一定不能取消);
(8).最后就是 Sprint Retrospective Meeting(回顧會議),也稱為總結會議,以輪流發言方式進行,每個人都要發言,總結并討論改進的地方,放入下一輪Sprint的產品需求中;
--->開發團隊(Scrum Team)(2)—(8)
主要負責軟件產品在Scrum規定流程下進行開發工作,人數控制在5~10人左右,每個成員可能負責不同的技術方面,但要求每成員必須要有很強的自我管理能力,同時具有一定的表達能力;成員可以采用任何工作方式,只要能達到Sprint的目標。
流程管理員(Scrum Master):跟蹤整個流程
主要負責整個Scrum流程在項目中的順利實施和進行,以及清除擋在客戶和開發工作之間的溝通障礙,使得客戶可以直接驅動開發。
XP方式
極限編程是一個輕量級的、靈巧的軟件開發方法;同時它也是一個非常嚴謹和周密的方法。它的基礎和價值觀是交流、樸素、反饋和勇氣;即,任何一個軟件項目都可以從四個方面入手進行改善:加強交流;從簡單做起;尋求反饋;勇于實事求是。XP是一種近螺旋式的開發方法,它將復雜的開發過程分解為一個個相對比較簡單的小周期;通過積極的交流、反饋以及其它一系列的方法,開發人員和客戶可以非常清楚開發進度、變化、待解決的問題和潛在的困難等,并根據實際情況及時地調整開發過程。
XP的一個成功因素是重視客戶的反饋——開發的目的就是為了滿足客戶的需要。
XP方法使開發人員始終都能自信地面對客戶需求的變化。
XP強調團隊合作,經理、客戶和開發人員都是開發團隊中的一員。團隊通過相互之間的充分交流和合作,使用XP這種簡單但有效的方式,努力開發出高質量的軟件。
XP的設計簡單而高效;程序員們通過測試獲得客戶反饋,并根據變化修改代碼和設計,他們總是爭取盡可能早地將軟件交付給客戶。
XP程序員能夠勇于面對需求和技術上的變化。
XP的十三種核心實踐:
1 團隊協作(Whole Team)
2 規劃策略(The Planning Game)
計劃是持續的、循序漸進的。每2周,開發人員就為下2周估算候選特性的成本,而客戶則根據成本和商務價值來選擇要實現的特性
3 小型發布(Small Release)
4 客戶測試(Customer Tests)
5 代碼集體所有權(Collective Code Ownership)
6 編碼規范(Coding Standards)
7 可持續開發(Sustainable Pace)
8 持續集成(Continuous Integration)
9 系統隱喻(System Metaphor)
隱喻同體系結構是同義詞,隱喻用于描述項目的全貌,Story用于描述個別具體的特征。隱喻是將整個系統聯系在一起的全局視圖;它是系統的未來影像,是它使得所有單獨模塊的位置和外觀變得明顯直觀。如果模塊的外觀與整個隱喻不符,那么你就知道該模塊是錯誤的
10 測試驅動開發(Testing-Driven Development)
編寫單元測試是一個驗證行為,更是一個設計行為。同樣,它更是一種編寫文檔的行為。編寫單元測試避免了相當數量的反饋循環,尤其是功功能能驗證方面的反饋循環。程序員以非常短的循環周期工作,他們先增加一個失敗的測試,然后使之通過
11 結對編程(Pair programming)
12 重構(Refactoring)
13 簡單設計(Simple Design)
四、著手一個新項目條理:文檔、測試用例、Gank
在著手一個項目前先讀文檔(如果有文檔的話)。盡管讀了文檔你不一定知道每一個代碼的細節,但是如果你了解那個問題的話,你一定知道怎么寫可以寫出一個滿足文檔的內容。這個時候大腦里面就可以有個框架,先猜一猜,然后看代碼,事半功倍。找不到好的文檔,就看他的測試用例,也是有一樣的功效的。因為測試都是從文檔出發編寫的,而不是從代碼出發編寫的。找不到文檔和測試用例?那就直接Gank吧。
讀代碼要層次化、帶著問題去閱讀。首先整體了解這個軟件是干什么?解決什么問題?包含哪些大的模塊,各個模塊的作用是什么,各個模塊的調用關系怎么樣?然后對于每一個模塊,這個模塊是干什么的?為什么要有這個模塊?這個模塊怎么實現的?最后細化到每一個包,每一個類,每一個函數方法。從上到下,一一擊破每一個問題,認真去思考他這樣設計、寫代碼的好處,因為好的軟件都會滿足這種從抽象->具體的原則的。
在開始讀具體代碼前定位好所有要讀的文件,知道他們的位置和名字,設計良好的工程光看工程的目錄結構和文件名就能知道個大概功能了。事實上閱讀代碼的難易程度70%取決于代碼書寫的規范程度,寫亂掉的代碼,大師也讀不懂。之后根據你對目錄結構的理解確定文件閱讀的順序(我反正都是從main函數開始讀的)。你最好對設計模式有一定了解,否則你讀面向對象的code時會經常無法理解code為啥要弄得這么層層嵌套。閱讀代碼一個最重要的提升水平的地方就是理解好的代碼如何合理使用設計模式。基本的閱讀起點都會選擇main函數或者類的構造函數。然后把自己想象成cpu執行程序那樣去閱讀你的代碼。遇到需要跳轉函數時,不要急于跳轉,以了解函數功能和輸入輸出為目標,讀代碼最忌諱的是不抓結構抓細節,只見樹木不見森林,比起某個函數具體功能來說對結構的全局把握更重要。功能了解清楚后繼續跳回來(這里就可以區分代碼寫的優不優秀,優秀的代碼光看函數名字就知道功能,連跳轉都不用)。結構弄清楚了,知道程序怎么跑了,source code的精華你已經讀了60%了,之后根據需要再對具體函數深入分析,到這里整個代碼已經被你扒光了,沒什么神秘了。
閱讀代碼有兩種模式:top-down 和 bottom-up。Top-down 模式,就是先設定一個 use case,比如說打開一個文件。然后靜態跟著代碼看,或者用 debugger 跟著看。每次出現函數調用的時候,把函數的執行層次紀錄下來。大致如下:
func1( )
func2(? )
func(? )
func3(? )
這種圖表很隨意,你可以根據自己的需要增加信息,可以把重要的「實際參數」一直標下來,畫函數調用圖,然后標注每個函數在干什么。不過這個圖無法清楚地表明一個變量的軌跡,需要另外的圖來標示變量的變化軌跡。要是想提高閱讀代碼的速度,歸根結底要多讀多寫。熟悉程序的基本構成單元(例如循環、分支)的常見寫法,各種lib, api的調用方式。這樣閱讀深層次代碼不用再回頭查形式參數到底指什么。這個圖的基本作用是防止在閱讀深層次代碼時忘記總體執行層次。Top-down 模式進行到一定層次,往往會發現雖然圖畫了出來,但還是無法了解程序在干什么。這時需要轉入 bottom-up 模式,一直深入到最底層,給能了解作用的底層函數一個一個的寫文檔。當然這時的文檔是完全底層的觀點。bottom-up的閱讀方法,有時候會一頭扎進去,出不來了。這種方式適合讀一些比較優秀的開源項目的代碼,也會很好地提高內功。然后就是不斷在兩個模式之間轉換,不斷的細化兩種模式的理解。
最后,對于OC工程可以去GitHub找UIViewController-Swizzled這個庫,拉下來放到項目里,他有什么用呢?他可以把每個頁面的類名打出來。而且有層次結構,也就是說你只需要打開項目點點點,就知道這個App運行的順序了。