banner
biuaxia

biuaxia

"万物皆有裂痕,那是光进来的地方。"
github
bilibili
tg_channel

【転載】大手企業の SDK の書き方を学びました!

title: 【転載】大手企業の SDK の書き方、学びました!
date: 2021-09-09 10:13:00
comment: false
toc: true
category:

  • Java
    tags:
  • 転載
  • Java
  • SDK
  • 書き方
  • 大手企業
  • 一般
  • 仕事
  • 必要

この記事は転載です:大手企業の SDK の書き方、学びました! - 掘金


自分で SDK を書く経験とテクニックの共有

皆さんこんにちは、私は魚皮です。

最近、仕事の必要から、いくつかのプロジェクトの一般的な SDK を自分で書きました。作成の過程で、他の企業の大物たちが書いた SDK を多く読み参考にし、SDK 開発の経験とテクニックをまとめましたので、皆さんに共有します〜

image

その前に、まず SDK とは何かを説明する必要があります。

SDK とは?#

SDK(Software Development Kit)とは ソフトウェア開発キット のことで、ソフトウェアを開発するためのツールの集合です。コードだけでなく、一般的にはドキュメントやサンプルなども含まれます。

一般的に SDK は プロジェクトに取り込む 必要があります。例えば、Java を学んでいる友人が最初に触れる JDK は、Java ソフトウェアを開発するためのツールキットで、使用する際には import java.util.* のような構文を書いて取り込む必要があります。また、大部分の SDK は、手動またはプロジェクト管理ツールを通じて、そのファイルを指定のパスにダウンロードしなければ取り込むことができません。

SDK の取り込み

SDK を使用する利点は何ですか?#

例えば、会社に多くのシステムがあり、ファイルアップロード機能を実装する必要があると仮定します。以前私の文章を読んだ友人は、優れたファイルアップロード機能は簡単ではないことを知っているはずです。多くの点を考慮する必要があります。例えば、分割、再開、秒送、ファイルストレージ、ファイル管理などです。

ファイルアップロード設計:mp.weixin.qq.com/s/3QXe4MSOb…

明らかに、私たちは各システムにファイルアップロードを開発する必要はなく、ただ一つのチームが身を捧げて、一般的な ファイルアップロード SDK を作成し、同じ機能を実装する必要があるシステムに取り込ませれば良いのです。これにより、作業量が大幅に削減され、開発効率が向上します

一般的な SDK

少し前人の車を作り、後人が楽しむという意味があります〜

SDK を作成することは 車輪を作る とも呼ばれます。良い車輪はチームの時間と労力を節約するだけでなく、同じ機能におけるプロジェクト間の差異を減らすこともできます。同じ機能であれば、小王が書いたものは 1 秒で動作し、小李が書いたものは 1 時間かかるということは避けたいものです!

もし各システムが同じ機能を開発することになれば、それは 車輪を繰り返し作る ことになり、大多数の場合、賢明な選択ではありません。

SDK が何であるかを理解した後、優れた SDK をどのように書くかを見てみましょう〜

手書き SDK 経験のまとめ#

良い SDK は、シンプルで使いやすく、わかりやすく、拡張しやすく、高効率で安定しているべきです。

使いやすさ#

今や、既製の車輪があまりにも多すぎます!あなたの車輪を際立たせるにはどうすればよいでしょうか?まずは SDK の使いやすさを向上させる必要があります。

私自身、技術選定の際には、シンプルで使いやすい SDK を優先的に選ぶ傾向があります。できれば数行のコードで簡単に使用できるものであり、長いドキュメントを読み終えた後に数十行のコードを書く必要があるものではありません。

製品の説明書と同じで、あまりにも複雑だと人を退かせてしまいます。

image

以下のポイントを通じて使いやすさを向上させることができます:

統一した呼び出し#

複雑な機能をカプセル化し、外部に統一された呼び出しエントリを提供し、実装の詳細をできるだけ隠蔽し、ユーザーの呼び出しプロセスとパラメータの理解コストを減らします。

例えば、以下は二つの日時処理関数です。ユーザーはそれらがどのように実装されているかを気にする必要はなく、どのように使うか、どのパラメータを渡すか、どのような戻り値を得るかを知っていれば良いのです。

// 第 1 種:オブジェクトを new する必要がある
DateUtils dateUtils = new DateUtils();
dateUtils.setDate('2021-08-31');
Date date = dateUtils.parse();

// 第 2 種:直接呼び出す
Date date = DateUtils.parse('2021-08-13');

皆さんはどちらが使いやすいと思いますか?

集中設定#

複雑なパラメータを設定可能にし、ユーザーがあちこちにパラメータを書く必要がなく、設定ファイルを通じて統一的に管理します。

Java の主流開発フレームワーク SpringBoot は典型的な例です。ユーザーが内蔵サーバーの起動ポートを変更したり、データベースの接続アドレスを変更したりする場合、コードを書く必要はなく、設定ファイルを変更するだけで済みます:

# サーバー設定
server:
  port: 8081
# データベース設定
db:
	ip: 10.0.0.1

また、これによりプロジェクトのメンテナンスや多環境の実現も容易になります。

良好な命名#

SDK の関数に名前を付ける際、できるだけユーザーの習慣に合ったものにします。

例えば、解析機能を持つ関数は "parseXXX" と名付けることができます。空であるかどうかを判断する関数は "xx.isEmpty" などです。できれば、ユーザーがドキュメントを見なくても、関数名とパラメータだけでその関数が何をするのかを理解できるようにします。

良い命名と悪い命名

したがって、良い SDK を書くためには、まず多くの使用と他の人の SDK を参考にし、習慣を身につけることで、皆がほぼ同じように命名していることに気づくでしょう。

しかし、注意が必要なのは、可能であれば、あなたの SDK のクラス名(関数名)が他の人と完全に一致しないようにすることです。そうしないと、ユーザーに混乱をもたらす可能性があります:同名の関数がこんなにたくさんあるのに、私はどれを使えばいいの?どれがあなたの開発した SDK なの?

理解しやすさ#

時には、ユーザーが単にあなたの SDK を使うだけでなく、SDK のソースコードを読んでさらに理解したいと思うこともあります。そうすれば、より安心して使えます。

したがって、使いやすさに加えて、SDK を理解しやすくする必要があります。外見は良いが中身が悪いということは避けなければなりません。

これはコーディング習慣に大きく関係しています。SDK を書くにせよ、プロジェクトを行うにせよ、以下のポイントを守る必要があります:

構造が明確#

コードを機能やカテゴリごとに整理し、指定のディレクトリに配置します。一般的な方法にはパッケージ分けや層分けなどがあり、各ディレクトリのファイルの役割が一目でわかるようにします。

例えば、以下のクラシックな Java プロジェクト構造では、service ディレクトリはビジネスロジックを記述するためのもので、constant は定数を格納するためのもので、utils はユーティリティクラスを格納するためのものなど、非常に明確です:

Java MVC プロジェクト構造

統一スタイル#

統一スタイルの目標は非常にシンプルです:プロジェクトが同じ人によって書かれたように見えることです。

例えば、コードのインデントはすべて 4 つのスペースを使用し、命名はキャメルケースを使用するなどです。特に機能が似ているコードは、命名と使用法の統一を保つ必要があります!例えば、テキストを解析する関数は、ある時は "parseXXX" と呼ばれ、またある時は "jiexiXXX" と呼ばれるのは避けるべきです。ユーザーを混乱させてしまいます〜

image

しかし、実際には、チーム開発ではこれを実現するのは非常に難しいです。だからこそ、一般的なコーディング規範が必要であり、皆がその規範を守ることで、プロジェクトがより理解しやすく、メンテナンスしやすくなります。

コメントの記述#

SDK の各クラスと関数の 先頭 にコメントを追加するのが最善です。これにより、ユーザーは SDK を使用する際、ドキュメントを見なくても、コードのコメントを見ればその機能や使い方がわかります。

Java SDK や有名な SDK の関数を適当に開いてみると、一般的にこれらのコメントが見られます。関数の機能の説明、パラメータの意味、戻り値の意味などが含まれています:

コメントの追加

説明文書#

コメントに加えて、SDK の取り込み方法、機能、使用方法などを含む説明文書(ユーザーマニュアル)を作成する必要があります。さらに、重要な実装の詳細や一般的な問題のリストを補足することもできます。

これもユーザーの選択に大きな影響を与えます。私個人の意見としては、ドキュメントがない SDK は一般的に選びません。万が一問題が発生した場合、誰に助けを求めればよいのか分からないからです。

image

拡張性#

SDK を作成する際の大きな難点は、一般的な使用シーンの大部分を考慮するだけでなく、一部のユーザーのカスタマイズされたニーズにも応える必要があることです。

したがって、SDK の拡張性は非常に重要ですが、どのように向上させるのでしょうか?

軽量依存#

一方で、SDK 自体が他のライブラリに依存するのをできるだけ減らすことができます。

例えば、非常に軽量なユーティリティクラスを作成する場合、数十 KB しかない場合、数百 KB の依存ライブラリを引き入れる必要はありません。得られるものよりも失うものが大きいです!他の人も使いたくないでしょう!

軽量依存は SDK のサイズを減らすだけでなく、依存の衝突の可能性を減らすことができます。私自身も、ツールクラスを取り入れた後、プロジェクト全体が動かなくなったという困った状況に何度も遭遇したことがあります!

image

カスタム実装#

SDK の汎用性と柔軟性を高めるために、SDK を設計する際には、デフォルトの実装を提供するだけでなく、ユーザーが継承して独自の実装方法を書くための一般的なインターフェースや抽象クラスを提供することをお勧めします。

例えば、日付解析クラスを作成する場合、デフォルトの解析ルールは短いハイフンで文字列を分割することとします:

// '-' で分割
date = DateUtils.parse('2021-01-18')

これだけでは、この SDK は非常に堅苦しいものになります。ユーザーはコロンや他のルールで解析したいかもしれません。

どう実現するか?

ユーザーが分割文字を自分で渡せるようにします:

// '-' で分割
parseRule = ':'
date = DateUtils.parse('2021-01-18', parseRule)

さらに、ユーザーが解析方法を制御できるようにします:

// カスタムパーサー
interface MyParser extends Parser {
  // ユーザーが自分で実装する必要があります
  void doParse();
}
// 指定されたパーサー
date = DateUtils.parse('2021-01-18', MyParser.class);

これら二つの方法は SDK の設計においてよく見られます。さらに、ユーザーが自分で設定ファイルを作成したり指定したりすることもでき、柔軟性を高めることができます。

効率と安定性#

実際、SDK を開発すること、特に大手企業で SDK を開発することは非常に「厄介」な仕事です。経験したことのある友人は共感できるでしょう。

SDK を使用するユーザーが増えるにつれて、さまざまな奇妙な問題が発生する可能性があります。また、SDK は比較的低レベルの依存関係であり、使用者に与える影響は計り知れません。したがって、頻繁にバグを修正するために残業したくないのであれば、SDK の安定性を確保する必要があります。

以下のポイントに注意する必要があります:

1. テスト#

各機能が正常であることを保証するために、単体テスト(UT)を作成して SDK の機能とコードを最大限にカバーします。

特に、コードを変更した後や新しいバージョンをリリースする前には、必ずテストを完全に実行してください。盲目的な自信を持たないでください。

インターフェーステストレポート

さらに、負荷テストを通じて SDK の実行効率を推定することもできます。例えば、毎秒最大 3 回同時に実行し、各回は 500 ミリ秒を要するなどです。これらの情報を説明文書に補足し、ユーザーに期待を持たせることをお勧めします。また、負荷テストを通じて SDK の性能を最適化することも試みることができます。

2. 互換性#

重要な関数やインターフェースは、特に関数名、引数、戻り値の変更をできるだけ減らします!

例えば、SDK の 0.1 バージョンでは、関数の定義は次のようになります:

boolean isValid(String str)

結果として、0.2 バージョンで突然次のように変更されると:

String checkValid(StringBuilder str)

これにより、ユーザーがアップグレードする際に困惑し、「なぜ関数が見つからないのか」となります。

image

したがって、大きな変更がある場合は、新しい関数を書き、古い関数には @Deprecated のような注釈を付けて、時代遅れであることを示し、ユーザーに新しいものを使うように誘導します。

さらに、バージョン番号に関しても工夫ができます。小さな変更の際は小バージョン番号だけを変更し、例えば 0.0.1 から 0.0.2 へ;大きな変更の際には大バージョン番号を変更します。例えば 1.0 から 2.0 へ。これにより、ユーザーに「今回の変更は大きいので、互換性がない可能性がある」と期待を持たせることができます。

3. 例外の露出#

ユーザーが SDK コード内で発生する可能性のある例外を認識できるようにし、適切な処理を行えるようにします。予期しないエラーが発生するのを防ぎます。

image

さらに、SDK は適切にログを出力する必要があります。特に例外ログについては、問題が発生した際に呼び出し元が何が問題であるかを知ることができるようにし、トラブルシューティングを容易にします。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。