web-dev-qa-db-ja.com

重大なAPIの変更:ライブラリユーザーが簡単に移行できるようにするにはどうすればよいですか?

以前は、標準の方法で@DeprecatedアノテーションをAPIメソッドに追加していましたが、今後のバージョンでは削除されます。

現在、ライブラリのメジャーバージョンを準備しています。多くのAPIパーツが削除され、名前が変更されています。

既存のユーザーが簡単に移行できるようにするには、新しいライブラリバージョンを古いバージョンと並べて使用できると便利な場合があります。

メリット

  • バージョン間の動的切り替えを実装できます
  • 新しいバージョンでバグが見つかった場合、アプリケーションは前のバージョンにフォールバックできます(ベータ段階で役立ちます)

これを行うには、新しいライブラリバージョンをcom.mycompany.libraryからcom.mycompany.library.v2に新しいパッケージに移動するだけです。

これは一般的な方法ですか、またはJavaライブラリの並列使用について他の推奨事項がありますか?


バックグラウンド:

ライブラリはシンプルなドキュメントコンバーターです。そのため、convert(in、out)メソッドのほかに、多くの構成プロパティといくつかのイベントハンドラーがあります。サイドバイサイドの使用法を提供する場合、コンシューマーは動的にインスタンス化して構成できます。

if (useVersion2) {
  com.mycompany.library.v2.Converter c = new com.mycompany.library.v2.Converter();
  // configure and run
  c.setOption(...);
  c.convert(in, out); 
} else {
  com.mycompany.library.Converter c = new com.mycompany.library.Converter();
  // configure and run
  c.setOption(...);
  c.convert(in, out);
}

(質問は https://stackoverflow.com/questions/37192945/ から移動しました)

8
mjn

このアプローチはかなり一般的です。新しいAPIへのスムーズな移行と、新しい実装への安全な進化を可能にします。

もちろん、ライヴの答えで強調されているように、if/thenアプローチにはいくつかの欠点があります。退屈です。忘れたり混同したりするのは簡単です。理想的には、ラッパー、ファクトリー、またはアダプターを使用すると、より優れた代替手段が提供される可能性があります。しかし、多くの場合、シンプルな方が良いです。

Martin FowlerとPete Hogdson は、最近、このトピックについて、彼らが「機能トグルパターン」と呼ぶものを説明する優れた記事で理論化しました。 「トグルルーター」の使用など、さまざまな実装戦略として興味深いかもしれません。使用シナリオについては、詳しく説明しています。

注:個人的に私は機能の切り替えを見つけられません。 C++の世界から来るので、使用するバージョンをコンパイル時に選択するために、名前空間のエイリアスと句を使用する、簡単で堅牢な代替手段を好みます。しかし、これは言語固有であり、さらに、機能が切り替わるときに動的構成を行うことはできません。したがって、前述のように、時々、シンプルな方が良いです;-)

3
Christophe

Retrofit ライブラリはこの良い例です。彼らはいくつかの破損をもたらしたとしても本当に良い安定したバージョン2を導入してからそれほど長くはありません。

彼らが行った注目すべきことのいくつかは次のとおりです。

  1. 新しいAPIには多くの価値があり、古いバージョンの多くの欠点に対処しています。つまり、新しいAPIは非常に優れている必要があります。それがどのように機能するかという点だけでなく、それが問題になった場合は、見栄えがよく簡単に見えるようにします。

  2. 新しいAPIのベータ版がリリースされ、ユーザーは変更を早い段階で知ることができ、適切なフィードバックを提供することもできます。

  3. 移行もそれほど苦痛ではありませんでした。彼らは、パッケージ名自体にバージョン番号を導入しました。つまり、一部の変更では、インポート文の変更のみが必要でした。はい、一部のクラスは削除され、一部は導入されましたが、それほど極端ではありませんでした。これは、ユーザーがコードベースをどのように編成したかにも依存しますが、これは部分的にAPI開発者の範囲外です。

さらに、移行ガイドが推奨されます。レトロフィットは人気のあるライブラリであり、これに関する多くの記事がオンラインで入手できます。

2
razzledazzle

if/elseでコードを分割するのは良い方法だとは思いません。

長期的に考えてください。今後のバージョンで何をしますか? )

どのようにしてユーザーコードが時間とともに存在するのですか?

マイナーバージョンまたはレビューについては、互換性を保つことが期待されます。 @ Deprecatedには、開発者にそのコードを使用しないように求めるコメントが付いています。また、代わりにcomponent/method/classを使用する必要があることも示唆しています。最後に、それらの多くは、非推奨のコードは今後のバージョンではサポートされないことを通知しています。またはサポートされていない可能性があります(彼らはまだ知りません)。

ただし、新しいバージョン(大幅な変更と再設計)では、保守が困難になるため、非推奨のコードを維持することはあまり意味がありません。レガシーコードもまた、加えられた変更によって影響を受ける可能性があります。直接かどうか。

また、使用方法が不明確になります。非推奨のコードに注釈が付けられていても。

あなたのケースが実際に大きな変更または改造である場合、私はむしろユーザーに新機能に移行することを推奨/強制します。

新しいlibが不審に見える場合、ユーザーは依存関係をダウングレードし、新しいlibのバグが解決されるまで依存関係を維持できます。

開発者として、あるバージョンから別のバージョンへの変更を期待しています。新しいものを使用することにした場合、そのような変更に対処するために受け入れます。

最悪のシナリオでは、前のシナリオに切り替えることができます。

「一時的」のような表現はしません。それがどのように終わるか私たちは皆知っているので...

むしろ、ユーザーがそのような確認に陥り、最終的にコードが読みにくく、維持が困難になるのを防ぐため

0
Laiv