*返回文件夾閱讀其它章節: http://blog.csdn.net/cuibo1123/article/details/39894477
git
類接口(class interface)github
你可以參考MGTileMenu的接口文件。api
咱們以前談論了一些接口的細節,這裏,例舉幾個通用規則:安全
規則1:使用當前平臺的描寫敘述用語或構架app
一個最多見的API錯誤設計是使用外來的規則,API屬於一個特定的平臺和相關開發人員生態系統。框架
你不能使用不論什麼其它不一樣平臺的描寫敘述用語或構架,這會污染你當前的代碼庫,並破壞你同伴的工做效率。ide
在編碼前要充分了解你的目標平臺和代碼規範。好比,在IOS和OSX中。不使用異常機制處理錯誤。函數
統一命名規則(規則要足夠具體,但是也要足夠簡潔)。ui
瞭解什麼是協議(protocol)。託付(delegate),擴展(category)。始終在你的代碼中使用術語。編碼
遵照構造函數和析構函數的有關命名方案。遵照本地內存管理規則。
就像在天然語言中詞彙和語法是不可切割的同樣,你的風格必需要符合指定平臺。
規則2: 設計解耦
設計時應該使組件和建立該組件的項目沒有關聯,假設是一個GUI組件或者視圖。那麼它應該顯示一些默認內容。利用現有的框架做爲指導,儘量讓託付協議(delegateprotocols)等交互保持鬆散耦合,適當的使用通知。並注意良好的設計和命名規則。
要作到這一點,爲每個組件建立一個單獨的測試項目是一個很是有效的方法。強迫組件僅僅使用本身的API。不要提取不相關的類之間的共同點。
如下讓咱們來看看類的接口。初始化方法是類接口中最重要的部分之中的一個,它決定用戶怎樣使用你的組件。
你的類需要對某些必要配置進行初始化。
因此,一個明顯的規則例如如下:
規則3: 所需的初始化條件應該由參數提供
假設有什麼必須的初始化設置,不要等待需要它的時候再去提供。而要在需要以前由初始化參數提供。
假設初始化沒有獲得所需的條件則立馬返回空(nil)。
// 需要參數,不能是nil
- (id)initWithDelegate:(id<MGTileMenuDelegate>)theDelegate;
規則4: 贊成訪問初始化參數
這是上一個規則的延續:切記不要把初始化時用戶提供的參數隱藏在模塊內部。要讓用戶可以訪問他們,並注意可否夠以某種方式改動(清除、或以其它方式改動)。
//必須經過初始化方法指定
@property (nonatomic, weak, readonly) id<MGTileMenuDelegate>delegate;
這是以上兩條規則共同擁有的演示樣例。
規則5: 凝視你的頭文件
實際上,你不會老是提供獨立的文檔來講明代碼功能。
假設你不提供獨立的文檔,那麼你的.h文件(以及演示程序)就是你的文檔。他們應該被「適當」的凝視,這裏所說的適當是指:
1:足夠具體,但是篇幅不要太長。
要足夠簡潔。
2:針對專業人員(語言和詞彙)。
所有假設必須足夠安全慎重。不要胡扯。不要含糊不清。
特別是,你應簡要說明參數、屬性的功能和默認值。讓用戶在頭文件裏很是easy檢索代碼功能,而不需要去看可執行代碼部分。
//瓦片背景漸變(default:藍)
@property (nonatomic) CGGradientReftileGradient;
// default: 5 pixels
@property (nonatomic) NSIntegerselectionBorderWidth;
// default:黑(底)白(頂)漸變
@property (nonatomic) CGGradientRefselectionGradient;
規則6: 集成到執行很少於3行代碼
你的類應該設計成僅僅需要很是少的代碼就可以集成到項目(不包括託付/數據源協議等)。不包括代理(delegate)方法。你的用戶應該僅僅使用三行代碼就能夠進行最簡單的測試,這些行各自是:1:實例化
2:基本配置。
3:顯示或激活它。
如下是來自MGTileMenu的相關代碼演示:
// 實例化.
tileController = [[MGTileMenuControlleralloc] initWithDelegate:self];
// 配置.
tileController.dismissAfterTileActivated = NO; // 使它更easy播放
// 顯示.
[tileControllerdisplayMenuCenteredOnPoint:locinView:self.view];
規則7: 一個繁雜的演示程序一般意味着組件功能零碎
還有一個推論: 你的演示程序大小決定了組件的質量。演示程序越小越好。演示所需代碼應該儘量的少而簡單(但是也要在demo中適當的演示組件的定製化服務或功能)。
使用一個空的Xcode模版,應該僅僅需要加入很是少的代碼,就可以建立具備你的組件核心功能的應用。僅僅提供一個演示程序是不夠的,還必須確保複製-粘貼你提供的演示樣例程序後相同可以工做。
規則8: 設置預約方案
我開發應用程序的標準規則是不給用戶提供配置選項,而是選擇合理的默認值來適用大部分用戶。
好的軟件。老是會執拗己見。
關於這一點。組件和應用程序有所不一樣,因爲組件的使用場景是不明白的。
固然,你可以讓組件僅僅適用於特定的某一種狀況,但一般咱們更但願組件具備必定的靈活性。
你永遠不知道其它開發人員會怎樣使用你的組件。所以,你必須讓它具備必定的通用性。
細緻考慮組件所支持的功能是很是重要的。
尤爲要考慮依賴關係-不是在編譯/連接時的依賴。而是邏輯功能與接口之間的依賴。個人作法是不在實例變量(成員)的層次去想這個問題。而是從「定製方案」的層次去想這個問題。
弄清楚你想讓你的組件具有哪些定製方案?而後依據這些定製方案,來選擇公開哪些屬性給使用者。
一個很是easy犯的錯誤是公開的配置項(接口)不足而削弱了某種功能,比方如下的一些樣例:
1:公開了寬度和高度設置,但是沒有考慮圓角。
2:公開了背景顏色的設置,但是沒有考慮高亮時的背景色設置。
3:公開了尺寸設置。但是沒有考慮間距。
這樣的錯誤一般取決於具體的組件,試着從顯示效果和功能的角度考慮屬性之間的關係。從用戶的角度來考慮問題。
要靈活易用。但不要放棄組件的特性。
// 解除菜單後瓦片被激活(YES; 默認)
@property (nonatomic) BOOLdismissAfterTileActivated;
// 右手模式(YES; 默認) 或左手模式(NO)
@property (nonatomic) BOOLrightHanded;
// 每個瓦片的寬高,單位:像素(默認72 像素)
@property (nonatomic) NSIntegertileSide;
// 瓦片間距, 單位:像素(默認: 20 像素)
@property (nonatomic) NSIntegertileGap;
// 瓷磚圓角的半徑, 單位:像素(默認: 12.0 像素)
@property (nonatomic) CGFloatcornerRadius;
讓常識指引你。
找到哪些在70%的狀況下都會使用的選項,並提供這些選項給用戶。
規則9: 不少其它的特性。更少的操做
在我喜歡的組件中(當中一些是標準框架。一些是來自第三方的開源組件,也有我本身寫的),有一個常常出現的特性。組件所實現的功能(所有功能,從初始化到狀態更新等)和公開的接口(存取器或本身定義方法等)存在必定的比例關係。
這些組件差點兒老是用更少的操做(這不是指界面上的操做,而是接口)來實現不少其它的特性。MGTileMenu有一個初始化和四個功能方法(當中一個是還有一個接口的簡化),以它的特性和操做來講,是四倍的比例關係。我以爲這是一個不錯的比例。在具備簡潔有用的功能的同一時候,也能靈活的定製。
// 參數不能爲nil
- (id)initWithDelegate:(id<MGTileMenuDelegate>)theDelegate;
// 從0開始
- (CGPoint)displayMenuPage:(NSInteger)pageNumcenteredOnPoint:(CGPoint)centerPtinView:(UIView *)parentView;
- (void)dismissMenu;
// 從0開始
- (void)switchToPage:(NSInteger)pageNum;
規則10: 在你的控件中使用控件
一個簡化API的很是好的方法是:在你的組件中使用現有的組件。組件風格統一併不意味着你不能利用現有組件來構造新的組件(實際上這是一個良好的軟件project基本原則)。
好比UITableViewCell和UIButton的API如此簡單。就是因爲它們使用了子控件UILabels和UIImageViews。假設合適,你也可以這樣作-並且暴露子控件,以便讓你當前的類接口更加簡潔一致。
好比MGTileMenu中,瓦片是由UIButtons擴展的。與在本身定義視圖中繪製並跟蹤輸入、提供訪問接口相比,這簡化了很是多工做。
規則11: 你的便利方法也可能適合用戶
你必定會在創做組件期間加入一些便利的方法,而又本能的將它們設爲私有(private)。
事實上。你可以考慮使用者在集成你的組件時是否會用到這些方法,以此來決定是否公開(public)它們。
好比,我在MGTileMenu中建立了這些便利的功能:
CGRectMGMinimallyOverlapRects(CGRectinner, CGRectouter, CGFloatpadding);
//RGB色彩漸變
CGGradientRefMGCreateGradientWithColors(UIColor *topColorRGB, UIColor *bottomColorRGB);
第一個是存儲位置的結構,用於移動菜單,以便它在其父視圖中可以全然可見(方便其它開發人員建立與他們本身的UI配套的菜單)。第二個是存儲漸變色的結構,用於爲菜單背景設置的圖形漸變(當背景改變後。會經過託付通知調用者)。
規則12: 奇妙的效果是好的,奇妙的數字不是
你早晚會在組件中放入一些奇特的東西。並但願賦予不少其它像史蒂夫·喬布斯式的使人愉快的奇妙特性。
但我要說的是在你的代碼中具備特殊含義的數字。一個最多見的樣例就是-1,它通常用來表示一組特別的東西,或特殊狀況。
用一個特定值表示一類狀況,這樣作很是正確。那麼什麼狀況是不對的那?顯然,不能在你的代碼中直接使用這樣的神奇的原始數值,尤爲是不能把它暴露在API中。假設你必須暴露它。請把它包裝一下,比方使用#defines定義一個可以讓人理解的名字。
閱讀下一章節: http://blog.csdn.net/cuibo1123/article/details/39894477
-------------------------
英文原名《API Design》
做者:Matt Gemmell
原名連接:http://mattgemmell.com/api-design/
中文版由xoneday翻譯
歡迎訪問譯者博客:http://blog.xoneday.com
新浪微博:@xoneday某天
假設這片譯文給您帶來了幫助。但願您能經過下載個人APP來支持我:
豆瓣讀書:https://itunes.apple.com/cn/app/id695492935
便籤夾:https://itunes.apple.com/cn/app/id580552733
便籤夾 豆瓣讀書
*轉載聲明:請勿刪減做者/譯者信息與支持部分的內容,如不接受此條款請勿轉載。