SoftwareEngineering.APIDesign.iOS

12736 ワード

API Design for iOS/Mac (Objective-c Edition)
 
1.UI Control Library APIの設計
既存のコンポーネントと一貫性を保つ(例えば、標準的なAPI、モデル、モードを使用する)ことで、Developerをより理解しやすくすることができます.
 
Class interface
Rule 1:このプラットフォームでよく使われる/一般的な用語または名前(Use the local dialect)を使用する
コードする前にこのプラットフォームの習慣や慣例を学ぶ.protocol,delegate,categoryはそれぞれ何なのかを学び理解します.メモリ管理規則に従う.
Rule 2:デカップリングの設計(Design decoupled)
"Any component should be designed such that it’s not coupled to the project you created it for,
and if it’s a GUI control or view, it should at least display something by default." Ref[1]
Rule 3:必要な設定はイニシエータのパラメータ(Required settings should be initializer parameters)とする 
 - (id)initWithDelegate:(id)theDelegate;//required parameter; cannot be nil. 
Rule 4:イニシエータへのアクセスを許可するパラメータ
1 @property (nonatomic, weak, readonly) id<MGTileMenuDelegate> delegate; // must be specified via initializer method.

 
Rule 5:ヘッダファイルにコメントを追加(Comment your header files(including defaults))
"you should briefly note default values beside properties or accessors"Ref[1]
1 @property (nonatomic) CGGradientRef tileGradient; // gradient to apply to tile backgrounds (default: a lovely blue)

2 @property (nonatomic) NSInteger selectionBorderWidth; // default: 5 pixels

3 @property (nonatomic) CGGradientRef selectionGradient; // default: a subtle white (top) to grey (bottom) gradient

Rule 6:3行のコードでコンポーネントを使用できることを確認します(Get up and running in 3 lines)
これは議論に値する. 
1 // Instantiate.

2 tileController = [[MGTileMenuController alloc] initWithDelegate:self];

3 

4 // Configure.

5 tileController.dismissAfterTileActivated = NO; // to make it easier to play with in the demo app.

6 

7 // Display.

8 [tileController displayMenuCenteredOnPoint:loc inView:self.view];

 
Rule 7:コンポーネントのdemoが小さいほど、コンポーネントを反映するのが良い(A fat demo usually means a broken component)
Rule 8:カスタムシーンを事前に考慮して満たす(Anticipate customisation scenarios)
"I approach this by trying not to think of customisation at the instance-variable level,
but rather at the “aspect” level."Ref[1]
Rule 9:より多くの属性、より少ない動作/方法(More properties,fewer actions)
Rule 10:あなたのコンポーネントに存在するコンポーネント(Use controls in your controls)を使用
Rule 11:便利な方法を開発者(Convenient for you is convenient for me)に暴露することを考える
Rule 12: (Magic is OK. Numbers aren’t)
"What’s not OK, though, is needlessly putting mysterious raw values throughout your code, and it’s 
especially not OK to expose that in the API."Ref[1]
 
Delegate and data-source protocols
Data-source Protocol注目事項:
  • How many things do I have?
  • What’s the value for property Y of thing X?

  • Delegateが注目している事項:
  • Should this thing do that?
  • This thing is about to do that.
  • This thing just did that.

  • should, will, did
     
    Rule 13:requiredメソッドの数を制限する(Limit‘required’delegate methods)
    "A well-designed component should need very, very few required delegate methods - just the
    bare minimum to do whatever it does."Ref[1]
    Rule 14:アクセス性のための設計(Design for accessibility)
    "make things accessible"Ref[1]
    accessibility programming VoiceOver
     
    Rule 15:パラメータの意味が明確なオブジェクト(Usesemantic objects for parameters)を使用
    "If you’re asking for a date, don’t accept numbers - get an actual NSDate object. "Ref[1]
     
    Rule 16:意味が適切でない場合、拡張API方式(Enhance the API if semantics don’t fit)を使用することができる
    例えば、「A contact list implemented with a table should have a contacts-related API」Ref[1]
     
    Rule:17 UIコンポーネントのハイライトが注目されます(Highlighting is interesting)
    Rule:18オプションの方法は承諾ではありません(Optional methods aren't a commitment)
    "Many of us approach optional delegate methods as an either-or situation: if you don’t implement them,
    you get the default behaviour, and if you do, then you’re totally responsible for what happens.
    That’s not ideal." ref[1] 
    オプションメソッドは、私たちが望む値を返さない可能性があります.たとえば、オプションメソッドはUIcolorオブジェクトを返すことを望んでいますが、オプションメソッドはnilを返します.では、
    デフォルトの論理に戻るのがより良い選択です.
    Rule 19:いつも誰が「話している」(Always say who’s talking)かを示す
    1 - (void)tileMenu:(MGTileMenuController *)tileMenu didActivateTile:(NSInteger)tileNumber; // zero-based tileNumber
    1 - (void)tileMenuDidActivateTile:(NSInteger)tileNumber; // zero-based tileNumber
    
    2 // Um, WHICH menu?

     
    Rule 20:異なるパラメータを前面に置く(Put distinguishing params first in query methods)
    1 - (UIImage *)imageForTile:(NSInteger)tileNumber inMenu:(MGTileMenuController *)tileMenu; // zero-based tileNumber
    1 - (UIImage *)tileMenu:(MGTileMenuController *)tileMenu imageForTile:(NSInteger)tileNumber;

     
    しかし、Apple APIは確かにこのRuleとは逆です.例えば、
    1 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

      
    Rule 21:senderをnotificationメソッドの最初のパラメータに配置する(Put the sender first in notification methods)
    "The One True Delegate Protocol, however, isn’t for queries but rather for notifications."Ref[1]
    1 - (void)tileMenu:(MGTileMenuController *)tileMenu willSwitchToPage:(NSInteger)pageNumber; // zero-based pageNumber

     
    Rule 22: If a convention is broken, throw it away (*)
     
    Notification
    "Notifications are the other half of delegate protocols. My position is that, if you’re using a delegate
    protocol (you should, if it’s at all appropriate), then it’s incomplete until you add the notifications
    that naturally follow from it."Ref[1]
     
    Rule 23:通知とdelegateメソッドが一致する(Notifications follow delegate methods)
    "If you have a delegate method that tells the delegate about something happening, you should
    usually provide a notification for that same purpose."Ref[1]
     
    Rule 24:notificationに十分なデータを提供する(Be generous with notifications'userInfo)
    "At the very least, you must ensure that all arguments provided to the corresponding delegate
    method are wrapped up in the userInfo object."Ref[1]
     
    Rule 25:テストを行う(Test the hell out of it)
    時間が迫っている場合は、featureを減らしてテストをサポートできます.
     
    Todo:  article on releasing open source code
     
    2. About iOS API Design
    2.1 Aviary team’s best practices for developing APIs
    "The design goals for an API are similar to those of a user interface: exposing the product’s features
    and communicating how to use them." Ref[2]
    2.1.1作成した文書はプラットフォームの約束を守らなければならない.
    2.1.2プラットフォームの一貫性
    "This manifests itself in long, descriptive method names, the organization of functionality around view controllers,
    and design patterns like delegation and target-action. "  Ref[2]
    AppleのCocoa Touch規範を遵守する:  naming conventions  and  design patterns  
    2.1.3 SDKの高速統合
    2.1.4適切なツールの選択:Best Pattern
    "Choosing the best pattern makes your code both easier to understand and to use."
     
    Delegate
    "the delegate version breaks up the processing code into pieces and makes it more difficult to read and understand."
    "Delegation is best suited for situations when the response to a notification relies primarily on the information
    contained in the delegate method’s parameters."
     
    2.1.5デフォルト値の提供 
    "By providing a convenience initializer, the integrating developer does not need to consider the more advanced
    options until their application demands them."
    2.1.6 SDKの後方互換性とバージョン情報の保守
     
    Reference
    1. API Design
    http://mattgemmell.com/api-design/
    主にUI側ライブラリとAPIの設計
    2. Best Practices for iOS API Design
    https://blog.creativesdk.com/2015/03/best-practices-for-ios-api-design/
    "Aviary team’s best practices for developing APIs" 
     
     
    Todo
    1. google "how to design interface of library for iOS"
    2. WWDC 2014 Session 416
    3. adobe creative sdk
    4. Delegate vs. Block
    google "delegate vs block ios"
    4.1 stablekernel.com/blog/blocks-or-delegates/
    4.2  Blocks: A Case Against Protocol Delegation
    http://mysteriousdevs.tumblr.com/post/29415817039/blocks-a-case-against-protocol-delegation
    4.3 Blocks vs Delegates – A Comparison
    http://www.abdus.me/ios-programming-tips/blocks-vs-delegates-ios-comparison/
    4.4 iOS blocks vs. selectors and delegates
    http://bradcupit.tumblr.com/post/3431169229/ios-blocks-vs-selectors-and-delegates
    4.5 http://www.slideshare.net/pohjus/ios-selectors-blocks-and-delegation
    4.6 Communicating with Blocks in Objective-C
    http://themainthread.com/blog/2012/09/communicating-with-blocks-in-objective-c.html
    4.7 Lessons from iOS dev #2: Delegates are good, blocks are better
    https://programmingthomas.wordpress.com/2013/04/21/lessons-from-ios-dev-2-delegates-are-good-blocks-are-better/
    4.8 Blocks vs Delegate
    http://corinnekrych.blogspot.tw/2013/06/blocks-vs-delegate.html
    4.9 Wrapping Objective-C Delegates with Blocks, Part 1
    http://pivotallabs.com/wrapping-delegates-blocks/
    4.10  When to use Delegation, Notification, or Observation in iOS
    http://blog.shinetech.com/2011/06/14/delegation-notification-and-observation/
    4.11 Replace common iOS delegate APIs with blocks
    https://gist.github.com/puppybits/1523687
    4.12 Delegate VS Block in API Design
    http://wangling.me/2014/01/delegate-vs-block-in-api-design.html
    4.13 Communication Patterns
    http://www.objc.io/issues/7-foundation/communication-patterns/
    4.14  Objective C Blocks: Summary, Syntax & Best Practices
    http://amattn.com/p/objective_c_blocks_summary_syntax_best_practices.html
    5. Delegate vs. Notification
    google "ios delegate vs notification"