YusukeYamamoto失敗から学ぶAPI設計山本 裕介@yusuke #ccc_h4
YusukeYamamoto前回までのあらすじ
YusukeYamamoto前回までのあらすじNo GGRKS!使ってもらうためにはどんな汚いことでもする対象プラットフォームを増やす外部ライブラリ非依存
YusukeYamamoto•Twitter APIのJavaラッパ•開発は2007年5月∼
YusukeYamamotoTwitter4Jは•再利用されているライブラリhttps://wiki.fitbit.com/display/API/API+Java+Client
YusukeYamamotoTwitter4Jは•再利用されているライブラリhttp://code.google.com/p/weibo4j/
YusukeYamamotoTwitter4Jは•再利用されているライブラリhttp://facebook4j.org
YusukeYamamotoTwitter4Jは•イイライブラリ
YusukeYamamotoTwitter4Jは•イイライブラリとは
YusukeYamamotoTwitter4Jは•イイライブラリとは• 優れたコストパフォーマンス• 機能が豊富• 品質が高い
YusukeYamamotoTwitter4Jは•イイライブラリ• 多くのユーザーが使っている• コミュニティが活発• 拡張しやすい• 使いやすい
YusukeYamamotoTwitter4Jは•イイライブラリ• 多くのユーザーが使っている• コミュニティが活発• 拡張しやすい• 使いやすい API・設計
YusukeYamamotoAPIとは• Application Programming Interface•何らかの機能を呼び出す口
YusukeYamamotoTwitter4JのAPIは•Twitter APIの射影
YusukeYamamotoTwitter4JのAPIは•Twitter APIの射影•現在のところ対象外• キャッシング・永続化• フレームワーク的なこと
YusukeYamamotoTwitter4J実装の変遷• バージョン1.0• Twitter APIのXMLのエンドポイント利用• バージョン2.0• OAuthサポート• domオブジェクトを保持しなくなった
YusukeYamamotoTwitter4J実装の変遷• バージョン2.1• 非推奨クラス、メソッドをバッサリ• Factoryの導入• バージョン2.2• Basic認証廃止• ライセンスをBSDからASLに変更
YusukeYamamotoTwitter4J実装の変遷• バージョン3.0• Twitter API 1.1対応
YusukeYamamotoTwitter4Jの開発指針
YusukeYamamotoシンプルに
YusukeYamamotoシンプルにYAGNI
YusukeYamamotoシンプル・YAGNI•クラス数は極力少なく
YusukeYamamotoシンプル・YAGNI•クラス数は極力少なく•インターフェースは(なるべく)使わない!
YusukeYamamotoシンプル・YAGNI•拡張ポイントはなるべく少なく
YusukeYamamoto(なるべく)immutableに
YusukeYamamotoTwitter4Jの拡張ポイント•クラス継承はさせない• 基本finalにして継承を防ぐ• 副作用を生まずに継承を許す設計はすごく難しい•strategyパターンとか言語道断(一部除く)
YusukeYamamotoシンプル・YAGNI•Twitter4Jの拡張ポイント• HTTP認証• 非同期ディスパッチャ• ロガー• HTTPクライアント
YusukeYamamotoシンプル・YAGNI•Twitter4Jの拡張ポイント• HTTP認証• 非同期ディスパッチャ• ロガー• HTTPクライアントほとんどのデベロッパは拡張しない
YusukeYamamotoデザインパターンを適用
YusukeYamamotoデザインパターンを適用しない
YusukeYamamotoデザインパターンを適用しないTwitter twitter = new Twitter();List<Status> statuses= twitter.getPublicTimeline();for(Status ...
YusukeYamamotoIDEの補完を活かせるように
YusukeYamamotoIDEの補完を活かせるようにhttp://www.youtube.com/watch?v=Nk9CUxEuUww補完の例
YusukeYamamotoIDEの補完が活きすぎないように• 使うべきでないクラス名を異様にする•z_T4JInternal******
YusukeYamamotoTwitter4Jの成長
YusukeYamamotoシンプルなTwitter4J32 KB
YusukeYamamotoシンプルだったTwitter4J5.1 MB32 KB
YusukeYamamoto互換性維持の苦労
YusukeYamamoto互換性維持の苦労•APIが増える•レスポンススキーマが変わる•ステータスコードが変わる•いつの間にか要素が増えてる•認証方式が変わる•エンドポイントURLが変わる...
YusukeYamamotoTwitter4Jの成長•Twitter APIの成長•Twitter4Jの成長• 膨らむクラス数• 膨らむメソッド数• 膨らむアクセサ数
YusukeYamamotoTwitter4Jの成長•至上命題互換性の維持
YusukeYamamoto互換性のために大事なこと•クラス名を変えない
YusukeYamamoto互換性のために大事なこと•メソッド名を変えない
YusukeYamamoto互換性のために大事なこと•挙動を変えない
YusukeYamamoto互換性のために大事なこと•直列化形式の互換性を保つ
YusukeYamamoto互換性のために大事なこと• 直列化形式の互換性を保つJava Object Serialization SpecificationVersioning of Serializable Objects5.6.1 Inco...
YusukeYamamoto互換性のために大事なこと• 非互換はコンパイラに検出させる
YusukeYamamoto互換性を維持できた例•User.java• ユーザー情報•UserWithStatus.java• ユーザー情報+αExtended user information with statusUser informat...
YusukeYamamoto互換性を維持できた例class User{}class UserWithStatus extends User{getFriendsCount();getFollowersCount();}バージョン1.0
YusukeYamamoto互換性を維持できた例class User{getFriendsCount();getFollowersCount();}/** @deprecated */class UserWithStatus extends U...
YusukeYamamoto互換性を維持できた例class User{getFriendsCount();getFollowersCount();}/** @deprecated */class UserWithStatus extends U...
YusukeYamamoto互換性を維持できた例class User{getFriendsCount();getFollowersCount();}/** @deprecated */class UserWithStatus extends U...
YusukeYamamotoTwitter4Jの失敗
YusukeYamamotoTwitter4Jの失敗•パッケージ分けの失敗•API設計の失敗
YusukeYamamotoパッケージ分けの失敗•パッケージ分け• twitter4j.*• twitter4j.api.*• twitter4j.auth.*• twitter4j.management.*• twitter4j.intern...
YusukeYamamotoパッケージ分けの失敗•パッケージ分けしすぎると• クラスが見つけられない• 特に貧弱なエディタを使っている場合• blogのコード例をコピペしても動かない• import部分の記載がないことが多い• JavaDocの...
YusukeYamamotoパッケージ分けの失敗•下手にパッケージ分けすると• 言語使用上仕方なくpublicなクラスが使われてしまうこのパッケージはあのパッケージに対してのみ公開、とかできるといいが少なくともJavaではできない。
YusukeYamamoto解決策• コードの見通しの問題であればパッケージ分けしない• かわりにソースディレクトリを分ける• クラス可視性はpackage privateで
YusukeYamamotomavenでソースディレクトリの分ける設定<plugin><groupId>org.codehaus.mojo</groupId><artifactId>build-helper-maven-plugin</arti...
YusukeYamamotoAPI設計の失敗Twitter twitter = new Twitter();
YusukeYamamotoAPI設計の失敗•コンクリートコンストラクタ•ユーザーにはわかりやすい•が、モックテストしづらいTwitter twitter = new Twitter();
YusukeYamamotoAPI設計の失敗• Twitterをクラスからインターフェースへ• Factoryを導入• Twitterインターフェースを実装したモックを作れるTwitter twitter= new TwitterFactory...
YusukeYamamotoAPI設計の失敗• やはりFactoryパターンは難しい• Singletonを返すstaticメソッドを導入• あまり知られていない、使われていないTwitter twitter= TwitterFactory.g...
YusukeYamamoto参考図書•Effective Java
YusukeYamamoto参考図書•Practical API Design
YusukeYamamoto#ccc_h4 #q?
失敗から学ぶAPI設計  #ccc_h4 #jjug #jjug_ccc JJUG CCC 2013 Spring
Upcoming SlideShare
Loading in...5
×

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

11,409

Published on

Published in: Technology
0 Comments
71 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
11,409
On Slideshare
0
From Embeds
0
Number of Embeds
20
Actions
Shares
0
Downloads
75
Comments
0
Likes
71
Embeds 0
No embeds

No notes for slide

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

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

×