失敗から学ぶAPI設計 #ccc_h4 #jjug #jjug_ccc JJUG CCC 2013 Spring

  • 10,230 views
Uploaded on

 

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
10,230
On Slideshare
0
From Embeds
0
Number of Embeds
20

Actions

Shares
Downloads
70
Comments
0
Likes
68

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. YusukeYamamoto失敗から学ぶAPI設計山本 裕介@yusuke #ccc_h4
  • 2. YusukeYamamoto前回までのあらすじ
  • 3. YusukeYamamoto前回までのあらすじNo GGRKS!使ってもらうためにはどんな汚いことでもする対象プラットフォームを増やす外部ライブラリ非依存
  • 4. YusukeYamamoto•Twitter APIのJavaラッパ•開発は2007年5月∼
  • 5. YusukeYamamotoTwitter4Jは•再利用されているライブラリhttps://wiki.fitbit.com/display/API/API+Java+Client
  • 6. YusukeYamamotoTwitter4Jは•再利用されているライブラリhttp://code.google.com/p/weibo4j/
  • 7. YusukeYamamotoTwitter4Jは•再利用されているライブラリhttp://facebook4j.org
  • 8. YusukeYamamotoTwitter4Jは•イイライブラリ
  • 9. YusukeYamamotoTwitter4Jは•イイライブラリとは
  • 10. YusukeYamamotoTwitter4Jは•イイライブラリとは• 優れたコストパフォーマンス• 機能が豊富• 品質が高い
  • 11. YusukeYamamotoTwitter4Jは•イイライブラリ• 多くのユーザーが使っている• コミュニティが活発• 拡張しやすい• 使いやすい
  • 12. YusukeYamamotoTwitter4Jは•イイライブラリ• 多くのユーザーが使っている• コミュニティが活発• 拡張しやすい• 使いやすい API・設計
  • 13. YusukeYamamotoAPIとは• Application Programming Interface•何らかの機能を呼び出す口
  • 14. YusukeYamamotoTwitter4JのAPIは•Twitter APIの射影
  • 15. YusukeYamamotoTwitter4JのAPIは•Twitter APIの射影•現在のところ対象外• キャッシング・永続化• フレームワーク的なこと
  • 16. YusukeYamamotoTwitter4J実装の変遷• バージョン1.0• Twitter APIのXMLのエンドポイント利用• バージョン2.0• OAuthサポート• domオブジェクトを保持しなくなった
  • 17. YusukeYamamotoTwitter4J実装の変遷• バージョン2.1• 非推奨クラス、メソッドをバッサリ• Factoryの導入• バージョン2.2• Basic認証廃止• ライセンスをBSDからASLに変更
  • 18. YusukeYamamotoTwitter4J実装の変遷• バージョン3.0• Twitter API 1.1対応
  • 19. YusukeYamamotoTwitter4Jの開発指針
  • 20. YusukeYamamotoシンプルに
  • 21. YusukeYamamotoシンプルにYAGNI
  • 22. YusukeYamamotoシンプル・YAGNI•クラス数は極力少なく
  • 23. YusukeYamamotoシンプル・YAGNI•クラス数は極力少なく•インターフェースは(なるべく)使わない!
  • 24. YusukeYamamotoシンプル・YAGNI•拡張ポイントはなるべく少なく
  • 25. YusukeYamamoto(なるべく)immutableに
  • 26. YusukeYamamotoTwitter4Jの拡張ポイント•クラス継承はさせない• 基本finalにして継承を防ぐ• 副作用を生まずに継承を許す設計はすごく難しい•strategyパターンとか言語道断(一部除く)
  • 27. YusukeYamamotoシンプル・YAGNI•Twitter4Jの拡張ポイント• HTTP認証• 非同期ディスパッチャ• ロガー• HTTPクライアント
  • 28. YusukeYamamotoシンプル・YAGNI•Twitter4Jの拡張ポイント• HTTP認証• 非同期ディスパッチャ• ロガー• HTTPクライアントほとんどのデベロッパは拡張しない
  • 29. YusukeYamamotoデザインパターンを適用
  • 30. YusukeYamamotoデザインパターンを適用しない
  • 31. YusukeYamamotoデザインパターンを適用しないTwitter twitter = new Twitter();List<Status> statuses= twitter.getPublicTimeline();for(Status status : statuses){System.out.println(status.getText());}多くのプログラマはFactoryとかわからないまずはコンクリートコンストラクタで。
  • 32. YusukeYamamotoIDEの補完を活かせるように
  • 33. YusukeYamamotoIDEの補完を活かせるようにhttp://www.youtube.com/watch?v=Nk9CUxEuUww補完の例
  • 34. YusukeYamamotoIDEの補完を活かせるように•なるべく同一パッケージに•一般的過ぎるクラス名にしない
  • 35. YusukeYamamotoIDEの補完が活きすぎないように• 使うべきでないクラス名を異様にする•z_T4JInternal******
  • 36. YusukeYamamotoTwitter4Jの成長
  • 37. YusukeYamamotoシンプルなTwitter4J32 KB
  • 38. YusukeYamamotoシンプルだったTwitter4J5.1 MB32 KB
  • 39. YusukeYamamoto互換性維持の苦労
  • 40. YusukeYamamoto互換性維持の苦労•APIが増える•レスポンススキーマが変わる•ステータスコードが変わる•いつの間にか要素が増えてる•認証方式が変わる•エンドポイントURLが変わる...
  • 41. YusukeYamamotoTwitter4Jの成長•Twitter APIの成長•Twitter4Jの成長• 膨らむクラス数• 膨らむメソッド数• 膨らむアクセサ数
  • 42. YusukeYamamotoTwitter4Jの成長•至上命題互換性の維持
  • 43. YusukeYamamoto互換性のために大事なこと•クラス名を変えない
  • 44. YusukeYamamoto互換性のために大事なこと•メソッド名を変えない
  • 45. YusukeYamamoto互換性のために大事なこと•挙動を変えない
  • 46. YusukeYamamoto互換性のために大事なこと•直列化形式の互換性を保つ
  • 47. YusukeYamamoto互換性のために大事なこと• 直列化形式の互換性を保つJava Object Serialization SpecificationVersioning of Serializable Objects5.6.1 Incompatible Changes5.6.2 Compatible Changeshttp://docs.oracle.com/javase/7/docs/platform/serialization/spec/version.html#6678• 現在の所テストケースはなく「気をつける」だけで互換性を保っている
  • 48. YusukeYamamoto互換性のために大事なこと• 非互換はコンパイラに検出させる
  • 49. YusukeYamamoto互換性を維持できた例•User.java• ユーザー情報•UserWithStatus.java• ユーザー情報+αExtended user information with statusUser information
  • 50. YusukeYamamoto互換性を維持できた例class User{}class UserWithStatus extends User{getFriendsCount();getFollowersCount();}バージョン1.0
  • 51. YusukeYamamoto互換性を維持できた例class User{getFriendsCount();getFollowersCount();}/** @deprecated */class UserWithStatus extends User{}バージョン1.0.4getterを上位クラスに移動
  • 52. YusukeYamamoto互換性を維持できた例class User{getFriendsCount();getFollowersCount();}/** @deprecated */class UserWithStatus extends User{}バージョン1.0.4UserWithStatusは非推奨、コンパイラが警告
  • 53. YusukeYamamoto互換性を維持できた例class User{getFriendsCount();getFollowersCount();}/** @deprecated */class UserWithStatus extends User{}バージョン2.0UserWithStatusを廃止、コンパイラがエラーを出す
  • 54. YusukeYamamotoTwitter4Jの失敗
  • 55. YusukeYamamotoTwitter4Jの失敗•パッケージ分けの失敗•API設計の失敗
  • 56. YusukeYamamotoパッケージ分けの失敗•パッケージ分け• twitter4j.*• twitter4j.api.*• twitter4j.auth.*• twitter4j.management.*• twitter4j.internal.*
  • 57. YusukeYamamotoパッケージ分けの失敗•パッケージ分けしすぎると• クラスが見つけられない• 特に貧弱なエディタを使っている場合• blogのコード例をコピペしても動かない• import部分の記載がないことが多い• JavaDocの読み方がわからないプログラマは非常に多い
  • 58. YusukeYamamotoパッケージ分けの失敗•下手にパッケージ分けすると• 言語使用上仕方なくpublicなクラスが使われてしまうこのパッケージはあのパッケージに対してのみ公開、とかできるといいが少なくともJavaではできない。
  • 59. YusukeYamamoto解決策• コードの見通しの問題であればパッケージ分けしない• かわりにソースディレクトリを分ける• クラス可視性はpackage privateで
  • 60. YusukeYamamotomavenでソースディレクトリの分ける設定<plugin><groupId>org.codehaus.mojo</groupId><artifactId>build-helper-maven-plugin</artifactId><executions><execution><id>add-source</id><phase>generate-sources</phase><goals><goal>add-source</goal></goals><configuration><sources><source>internal-json</source><source>internal-async</source></sources></configuration></execution></executions></plugin>
  • 61. YusukeYamamotoAPI設計の失敗Twitter twitter = new Twitter();
  • 62. YusukeYamamotoAPI設計の失敗•コンクリートコンストラクタ•ユーザーにはわかりやすい•が、モックテストしづらいTwitter twitter = new Twitter();
  • 63. YusukeYamamotoAPI設計の失敗• Twitterをクラスからインターフェースへ• Factoryを導入• Twitterインターフェースを実装したモックを作れるTwitter twitter= new TwitterFactory().getInstance();
  • 64. YusukeYamamotoAPI設計の失敗• やはりFactoryパターンは難しい• Singletonを返すstaticメソッドを導入• あまり知られていない、使われていないTwitter twitter= TwitterFactory.getSingleton();
  • 65. YusukeYamamoto参考図書•Effective Java
  • 66. YusukeYamamoto参考図書•Practical API Design
  • 67. YusukeYamamoto#ccc_h4 #q?