2

まず、はい、この質問は主観的なものかもしれません。ただし、関連するすべての要因を考慮に入れると、おそらく「最良の」答えがあると思います。いずれにせよ、試してみる価値はあります:)

A、B、C の 3 つのライブラリがあるとします。

ライブラリ B はライブラリ A を使用します。ライブラリ C はライブラリ A を使用します。

A、B、Cを一緒に使ったり、A、B、Cを好きなように組み合わせて飲んだりできるようにしてほしいです。

ライブラリをソース コードと共に配布できるようにしたいと考えています。これにより、必要に応じてライブラリを自分でビルドしたり、個々のファイルを取得して使用したりできるようになります。

それらを 1 つの大きなモノリシックな塊にまとめて配布したくはありません。

かさばるという問題は別として、私がこれをやりたくないのには十分な理由があります。B が、一緒に動作するように設計された他のライブラリに外部依存しているとしましょう。C を使用したいだけの人に、B が使用しているという理由だけで、他のライブラリにリンクするように強制したくありません。したがって、A、B、C を 1 つのパッケージにまとめるのはよくありません。

私は、単に C が欲しいだけの人が、C を手に入れて、それで作業するために必要なものがすべて揃っていることを簡単に理解できるようにしたいと考えています。

これに対処する最善の方法は次のとおりです。

  • 問題の言語はObjective-cです
  • 私の好みの配信メカニズムは 1 つ以上のフレームワークです (ただし、他のオプションを検討します)
  • 私の好みのホスティング メカニズムは git / github です
  • パッケージマネージャーは必要ない

これは比較的簡単な質問のように思えますが、実際には非常に微妙な質問であることをお伝えしておきます。説明のために、いくつかの可能な解決策とおそらく欠陥のある解決策を次に示します。

封じ込め/サブモジュール

B と C が A を使用しているという事実は、おそらく A を含める必要があることを示唆しています。これは、git サブモジュールを使用して簡単に実現できます。しかし、もちろん、自分のプロジェクトで B と C の両方を使用している人は、A のコピーを 2 つ持つことになります。彼らのコードで A も使用したい場合、どちらを使用しますか? B と C に A のわずかに異なるリビジョンが含まれている場合はどうなるでしょうか?

相対位置

別の方法として、B と C をセットアップして、A のコピーが B と C に関連する既知の場所 (たとえば、B と C と同じ格納フォルダー) に存在することを期待するようにします。

このような:

libs/
  libA/
  libB/ -- expects A to live in ../
  libC/ -- expects A to live in ../

これは良さそうに聞こえますが、「C を取得してすべてを取得できるようにする」というテストには失敗します。C をつかむだけでは十分ではなく、A をつかんで正しい場所に配置する必要もあります。

これは面倒です。たとえば、自動化されたテストをセットアップしたい場合は、自分でこれを行う必要があります。しかし、それより悪いのは、A のどのバージョンですか? A の特定のバージョンに対してのみ C をテストできます。そのため、それを公開するときに、他の人がそのバージョンを取得できるようにするにはどうすればよいでしょうか。B と C に異なるバージョンが必要な場合はどうなりますか?

暗黙の要件

これは上記の「相対位置」のバリエーションです。唯一の違いは、A が特定の相対位置にあることを期待するように C のプロジェクトを設定するのではなく、検索パスにあることを期待するように設定するだけです。どこか。

これは、特に Xcode のワークスペースを使用して可能です。C のプロジェクトが、A も追加されているワークスペースに追加されることを期待している場合は、C が A を見つけられるように調整できます。

ただし、これは「相対位置」ソリューションの問題には対処しません。そのワークスペースが A の相対的な位置について仮定しない限り、例のワークスペースで C を出荷することさえできません!

階層化されたサブモジュール

上記のソリューションのバリエーションは次のとおりです。

  • A、B、C はすべて独自のリポジトリに存在します
  • BまたはCをビルドおよびテスト(または使用)できるように、物事を適切に配置する公開「統合」リポジトリ(BIおよびCIと呼びましょう)を作成します。

したがって、CI には以下が含まれる可能性があります。

- C.xcworksheet
- modules/
    - A (submodule)
    - C (submodule)

これでだいぶ良くなりました。誰かが C を使いたいだけなら、CI を入手してすべてを手に入れることができます。

サブモジュールであるため、正しいバージョンを取得できます。新しいバージョンの CI を公開すると、暗黙のうちに「このバージョンの C はこのバージョンの A で動作する」ということになります。うまくいけば、あなたがそれをテストしたと仮定します。

CI を使用する人は、ビルド/テスト用のワークスペースを取得します。CI リポジトリには、サンプル コードやサンプル プロジェクトなどを含めることもできます。

ただし、B と C を一緒に使用したい場合は、まだ問題があります。BI と CI だけを使用すると、最終的に A の 2 つのコピーが作成されます。これは衝突する可能性があります。

さまざまな組み合わせで階層化されたサブモジュール

ただし、上記の問題は克服できないわけではありません。

次のような BCI リポジトリを提供できます。

- BC.xcworkspace
- modules/
    - A (submodule)
    - B (submodule)
    - C (submodule)

あなたが「B と C を一緒に使いたいなら」と言っているなら、私が動作することがわかっているディストリビューションがあります。

これはすべて良いように聞こえますが、維持するのが少し難しくなっています。現在、A、B、C、BI、CI、BCI のリポジトリのさまざまな組み合わせを維持し、プッシュする必要がある可能性があります。

これまでのところ、3 つのライブラリについてのみ説明しています。これは私にとっては本当の問題ですが、現実の世界では潜在的に約 10 個あります。それは痛いです。

だから、あなたへの私の質問は次のとおりです。

  • あなたならどうしますか?
  • より良い方法はありますか?
  • 小さなモジュールと大きなモノリシック フレームワークの間の選択は、モジュールのユーザーにとってより優れた柔軟性と、メンテナーにとってより多くの作業との間のトレードオフであることを受け入れる必要がありますか?
4

2 に答える 2

2

ライブラリはタマネギのようなもので、たくさんのレイヤーがあります。そして、レイヤー違反は厄介なタマネギになります。内層に外層を含めることはできません。

  • 3 つの個別の静的ライブラリ プロジェクトを作成します (iOS をターゲットにしている可能性があると仮定します)。A、B、C

  • B には A からのヘッダーを含めることができ、C には A からのヘッダーを含めることができます

  • B と C には、互いのヘッダーを含めることはできません。A に B または C からのヘッダーを含めることはできません

  • サポートするライブラリの組み合わせごとにワークスペースを作成します

  • 適切なプロジェクトをワークスペースに追加する

  • 各ワークスペースに新しいプロジェクトを作成して、その組み合わせのテスト アプリや単体テストを含めます。

鍵はワークスペースです。ワークスペースを使用すると、プロジェクトの任意のセットを組み合わせることができます。それらの構成が同じである限り (デバッグとリリース)、ビルド/実行/分析/プロファイルによって依存関係が適切に判断されます (手動で設定できます)。すべてを単一の派生データ/製品フォルダーに組み込むだけで機能します。

たとえば、C プロジェクトをスタンドアロンでビルドする場合は、A を期待どおりに (通常は /usr/local/ にインストールしますが、~/ にもインストールできます)、顧客のシステムとまったく同じようにインストールする必要があります (バイナリ ライブラリのインストールをサポートする場合)。

これはまさに、Apple でプロジェクトを管理している私たちの数であり、非常にうまく機能しています。管理に関しては、できるだけシンプルに保ちます。チーム全体がビルドと構成に専念する可能性は低いため、構成はシンプルにする必要があります。

状況を正直に評価し、A が B によって使用されることはないと結論付ける場合は、B を A に折りたたんで、それで完了です。再利用可能な API をうまく書くのは非常に困難です。私は、多くのプロジェクトが、1 つの特定の用途のみを対象とした完全に一般化されたソリューションを作成しようとして行き詰まり、その過程で膨大な時間を浪費している (そして時には失敗している) のを見てきました。

于 2012-08-11T14:25:14.067 に答える
1

注意しながら

パッケージマネージャーは必要ない

CocoaPodsをお勧めします。深い依存関係管理など、他のすべてのことを実行し、git に非常に使いやすく、全体的にインストールと使用が非常に簡単です。

それでも、これは要件に関して正確な答えではありません。

于 2012-08-12T16:47:02.687 に答える