Spring Bootハンズオン ~Spring Bootで作る マイクロサービスアーキテクチャ! #jjug_ccc #ccc_r53
失敗から学ぶAPI設計 #ccc_h4 #jjug #jjug_ccc JJUG CCC 2013 Spring
-
Upload
yusuke-yamamoto -
Category
Technology
-
view
10.209 -
download
0
description
Transcript of 失敗から学ぶAPI設計 #ccc_h4 #jjug #jjug_ccc JJUG CCC 2013 Spring
Yusuke Yamamoto
失敗から学ぶAPI設計山本 裕介
@yusuke #ccc_h4
Yusuke Yamamoto
前回までのあらすじ
Yusuke Yamamoto
前回までのあらすじ
No GGRKS!
使ってもらうためにはどんな汚いことでもする
対象プラットフォームを増やす
外部ライブラリ非依存
Yusuke Yamamoto
• Twitter APIのJavaラッパ•開発は2007年5月~
Yusuke Yamamoto
Twitter4Jは•再利用されているライブラリ
https://wiki.fitbit.com/display/API/API+Java+Client
Yusuke Yamamoto
Twitter4Jは•再利用されているライブラリ
http://code.google.com/p/weibo4j/
Yusuke Yamamoto
Twitter4Jは•再利用されているライブラリ
http://facebook4j.org
Yusuke Yamamoto
Twitter4Jは•イイライブラリ
Yusuke Yamamoto
Twitter4Jは•イイライブラリとは
Yusuke Yamamoto
Twitter4Jは•イイライブラリとは• 優れたコストパフォーマンス• 機能が豊富• 品質が高い
Yusuke Yamamoto
Twitter4Jは•イイライブラリ• 多くのユーザーが使っている• コミュニティが活発• 拡張しやすい• 使いやすい
Yusuke Yamamoto
Twitter4Jは•イイライブラリ• 多くのユーザーが使っている• コミュニティが活発• 拡張しやすい• 使いやすい API・設計
Yusuke Yamamoto
APIとは• Application Programming Interface•何らかの機能を呼び出す口
Yusuke Yamamoto
Twitter4JのAPIは• Twitter APIの射影
Yusuke Yamamoto
Twitter4JのAPIは• Twitter APIの射影
•現在のところ対象外• キャッシング・永続化• フレームワーク的なこと
Yusuke Yamamoto
Twitter4J実装の変遷• バージョン1.0• Twitter APIのXMLのエンドポイント利用• バージョン2.0• OAuthサポート• domオブジェクトを保持しなくなった
Yusuke Yamamoto
Twitter4J実装の変遷• バージョン2.1• 非推奨クラス、メソッドをバッサリ• Factoryの導入• バージョン2.2• Basic認証廃止• ライセンスをBSDからASLに変更
Yusuke Yamamoto
Twitter4J実装の変遷• バージョン3.0• Twitter API 1.1対応
Yusuke Yamamoto
Twitter4Jの開発指針
Yusuke Yamamoto
シンプルに
Yusuke Yamamoto
シンプルに
YAGNI
Yusuke Yamamoto
シンプル・YAGNI•クラス数は極力少なく
Yusuke Yamamoto
シンプル・YAGNI•クラス数は極力少なく•インターフェースは(なるべく)使わない!
Yusuke Yamamoto
シンプル・YAGNI•拡張ポイントはなるべく少なく
Yusuke Yamamoto
(なるべく)immutableに
Yusuke Yamamoto
Twitter4Jの拡張ポイント•クラス継承はさせない• 基本finalにして継承を防ぐ• 副作用を生まずに継承を許す設計はすごく難しい
• strategyパターンとか言語道断(一部除く)
Yusuke Yamamoto
シンプル・YAGNI• Twitter4Jの拡張ポイント• HTTP認証 • 非同期ディスパッチャ• ロガー• HTTPクライアント
Yusuke Yamamoto
シンプル・YAGNI• Twitter4Jの拡張ポイント• HTTP認証 • 非同期ディスパッチャ• ロガー• HTTPクライアントほとんどのデベロッパは拡張しない
Yusuke Yamamoto
デザインパターンを適用
Yusuke Yamamoto
デザインパターンを適用しない
Yusuke Yamamoto
デザインパターンを適用しないTwitter twitter = new Twitter();
List<Status> statuses = twitter.getPublicTimeline();
for(Status status : statuses){ System.out.println(status.getText());}
多くのプログラマはFactoryとかわからないまずはコンクリートコンストラクタで。
Yusuke Yamamoto
IDEの補完を活かせるように
Yusuke Yamamoto
IDEの補完を活かせるように
http://www.youtube.com/watch?v=Nk9CUxEuUww
補完の例
Yusuke Yamamoto
IDEの補完を活かせるように•なるべく同一パッケージに•一般的過ぎるクラス名にしない
Yusuke Yamamoto
IDEの補完が活きすぎないように• 使うべきでないクラス名を異様にする• z_T4JInternal******
Yusuke Yamamoto
Twitter4Jの成長
Yusuke Yamamoto
シンプルなTwitter4J
32 KB
Yusuke Yamamoto
シンプルだったTwitter4J
5.1 MB32 KB
Yusuke Yamamoto
互換性維持の苦労
Yusuke Yamamoto
互換性維持の苦労•APIが増える•レスポンススキーマが変わる•ステータスコードが変わる•いつの間にか要素が増えてる•認証方式が変わる•エンドポイントURLが変わる...
Yusuke Yamamoto
Twitter4Jの成長• Twitter APIの成長
• Twitter4Jの成長• 膨らむクラス数• 膨らむメソッド数• 膨らむアクセサ数
Yusuke Yamamoto
Twitter4Jの成長•至上命題
互換性の維持
Yusuke Yamamoto
互換性のために大事なこと•クラス名を変えない
Yusuke Yamamoto
互換性のために大事なこと•メソッド名を変えない
Yusuke Yamamoto
互換性のために大事なこと•挙動を変えない
Yusuke Yamamoto
互換性のために大事なこと•直列化形式の互換性を保つ
Yusuke Yamamoto
互換性のために大事なこと• 直列化形式の互換性を保つJava Object Serialization Specification Versioning of Serializable Objects 5.6.1 Incompatible Changes 5.6.2 Compatible Changeshttp://docs.oracle.com/javase/7/docs/platform/serialization/spec/version.html#6678
• 現在の所テストケースはなく「気をつける」だけで互換性を保っている
Yusuke Yamamoto
互換性のために大事なこと•非互換はコンパイラに検出させる
Yusuke Yamamoto
互換性を維持できた例•User.java• ユーザー情報
• UserWithStatus.java• ユーザー情報+α
Extended user information with status
User information
Yusuke Yamamoto
互換性を維持できた例
class User{}
class UserWithStatus extends User{ getFriendsCount();getFollowersCount();}
バージョン1.0
Yusuke Yamamoto
互換性を維持できた例
class User{ getFriendsCount();getFollowersCount();}/** @deprecated */class UserWithStatus extends User{}
バージョン1.0.4
getterを上位クラスに移動
Yusuke Yamamoto
互換性を維持できた例
class User{ getFriendsCount();getFollowersCount();}/** @deprecated */class UserWithStatus extends User{}
バージョン1.0.4
UserWithStatusは非推奨、コンパイラが警告
Yusuke Yamamoto
互換性を維持できた例
class User{ getFriendsCount();getFollowersCount();}/** @deprecated */class UserWithStatus extends User{}
バージョン2.0
UserWithStatusを廃止、コンパイラがエラーを出す
Yusuke Yamamoto
Twitter4Jの失敗
Yusuke Yamamoto
Twitter4Jの失敗•パッケージ分けの失敗• API設計の失敗
Yusuke Yamamoto
パッケージ分けの失敗•パッケージ分け• twitter4j.*• twitter4j.api.*• twitter4j.auth.*• twitter4j.management.*• twitter4j.internal.*
Yusuke Yamamoto
パッケージ分けの失敗•パッケージ分けしすぎると• クラスが見つけられない• 特に貧弱なエディタを使っている場合• blogのコード例をコピペしても動かない• import部分の記載がないことが多い• JavaDocの読み方がわからないプログラマは非常に多い
Yusuke Yamamoto
パッケージ分けの失敗•下手にパッケージ分けすると• 言語使用上仕方なくpublicなクラスが使われてしまうこのパッケージはあのパッケージに対してのみ
公開、とかできるといいが少なくともJavaでは
できない。
Yusuke Yamamoto
解決策• コードの見通しの問題であればパッケージ分けしない• かわりにソースディレクトリを分ける• クラス可視性はpackage privateで
Yusuke Yamamoto
mavenでソースディレクトリの分ける設定<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>
Yusuke Yamamoto
API設計の失敗
Twitter twitter = new Twitter();
Yusuke Yamamoto
API設計の失敗•コンクリートコンストラクタ
•ユーザーにはわかりやすい•が、モックテストしづらい
Twitter twitter = new Twitter();
Yusuke Yamamoto
API設計の失敗• Twitterをクラスからインターフェースへ• Factoryを導入
• Twitterインターフェースを実装したモックを作れる
Twitter twitter = new TwitterFactory().getInstance();
Yusuke Yamamoto
API設計の失敗• やはりFactoryパターンは難しい• Singletonを返すstaticメソッドを導入
• あまり知られていない、使われていないTwitter twitter = TwitterFactory.getSingleton();
Yusuke Yamamoto
参考図書•Effective Java
Yusuke Yamamoto
参考図書•Practical API Design
Yusuke Yamamoto
#ccc_h4 #q
?