なぜ内部アプリケーション用の内部ライブラリを開発するのですか?


10

内部アプリケーションの開発専用に使用する内部ライブラリを開発する必要がある理由を理解できません。組織外の誰かが作成したソフトウェアを使用したい場合は、ヘッダーファイルと.aまたは.soファイルを送ってプロジェクトにリンクするだけでよい(同じ環境でコンパイルされていると仮定) 。

しかし、ヘッダーと実装ファイルにアクセスでき、それらをソースツリーに含めてすべて一緒にコンパイルできるときに、内部ライブラリを内部アプリケーションにリンクするためだけに開発する必要があるのはなぜですか?

つまり、ソースコードが記述されている場合、それをバイナリライブラリにコンパイルしてアプリケーションにリンクするか、プロジェクトのソースファイルに含めて定期的にコンパイルするだけにするかをどのように決定しますか?

各プロジェクトに「インクルード」ファイルと言っても、現在開発中のプロジェクトのソースツリーに各ファイルをコピーして貼り付けることを意味するものではありません。通常の方法でプロジェクトのファイルに含めることができる共通のソースコード(#includeなど)を含む(任意のプロジェクトとは別の)ディレクトリ/ライブラリを開発することを意味します。

psここでは、複数のデスクトップアプリケーション用のc / c ++開発について話しています。


回答:


25

内部で使用する場合でも、ライブラリと共有ライブラリを(.dllまたは.soファイルで)作成する理由は数多くあります。

  1. プロジェクト間での再利用ははるかにきれいです
  2. 責任の分離-コードの一部は、より適切な異なる開発者またはチームである可能性があります
  3. 特定のコードを見つけることなく、他のチームが作成したライブラリの改善から利益を得ることができます
  4. ビルド時間が短縮されます。ライブラリが安定している場合は、再ビルドする必要はありません。
  5. ディスク容量-ライブラリとヘッダーのみをプロジェクトに含めることができます
  6. 共有ライブラリを使用すると、複数のプログラムが使用している場合でも、RAMにコピーを1つだけロードすることでメモリを節約できます
  7. 一般的に、ライブラリのドキュメントとテストが改善されます。
  8. クリーナーの設計とコード-ライブラリに構造化することについての考え方は、各ライブラリにおける機能の関連グループをもたらすべきである、あなたは、汎用コードを分離する傾向があるライブラリに、アプリケーションの仕様から、アプリで
  9. ライブラリに独自のアルゴリズムがある場合は、ソースへのアクセスを制限できます。たとえば、請負業者や外部のチームがソースにアクセスできないようにします。
  10. ライブラリのコードは、それが元々の一部として書かれたアプリケーションに異なるライセンスの下に置くことができる、いくつかの企業も、彼らは誇りに思っていることを、オープンソースのライブラリに知られている- 貢献したオープンソース・コミュニティの主要な賛辞といつか主要な拡張機能を獲得しますバック。

一部の企業は、ライブラリを作成するプロジェクトが再利用するたびにいくらか払い戻しを受ける会計慣行を持っています。


1
または、ポイント9のバリエーションでは、メインアプリケーションコードとは異なるライセンスでライブラリをリリースできます。
Michael Borgwardt 2017

@MichaelBorgwardt-上記のポイント10を促す良い点。
Steve Barnes

また、いくつかのコードを個別のライブラリとして持つと、「ここにこの追加のパラメーターを追加するだけです」などのプログラミング中のショートカットを回避し、必要な機能を実装するためのより良い方法を見つけることができます。
Valdas 2017

11

大規模で重要なプロジェクトに適用される可能性のあるその他の考えられる理由:

  • コンパイル時間:数千のファイル、数千のクラス、関数などを含む巨大なモノリシックC ++プロジェクトは、コンパイルに非常に長い時間がかかる可能性があります(数行のコードを変更するたびに再コンパイルする場合、生産性が低下します)。静的にリンクされたライブラリと動的にリンクされたライブラリは個別にコンパイルされ、ソースが変更されていない場合は再コンパイルする必要はありません。

  • 個別のモジュールまたはサブシステムの論理的な分離:機能の個別の領域が個別のモジュールに配置されている場合、大規模なシステムは通常管理が容易であり、開発者は何千ものファイル/クラスを含む巨大なフォルダー/プロジェクトを検索する必要がありません。

  • 開発者/チーム間の境界:別々の新しい機能を同時に開発する開発者は、各開発者が異なるモジュールで作業することが可能であれば、マージの競合の可能性を減らすことができます。

  • ライブ環境にリリースしてはならないコード:たとえば、開発者テストでライブシステムコンポーネント(ハードウェア、API、リモートシステム、データベースなど)の代わりに使用される単体テストライブラリまたは「モック」ライブラリ

  • コンパイラフラグ:奇妙なコンパイラフラグが必要なサードパーティのAPIと統合するという非常に不幸な立場にいる場合、ライブラリはサードパーティのAPIとアプリケーションの残りの部分の間にある「汚染除去層」になる可能性があります。

  • オプション機能/最適化:大規模なシステムでは、アプリケーションの基本的な機能にとって重要ではない場合、特定の動的にリンクされたモジュールを実行時にメモリにロードする前に、アプリケーションが待機する場合があります。


一般に、多くの内部プロジェクトは小さなマイクロアプリであることが多く、個別のライブラリに分割してもメリットがありません。小さなプロジェクトで単独の開発者として作業している場合は、コードをライブラリに分割することを心配する必要はありません(まだ...)。YAGNI原則を忘れないでください。


3
@downvoter-反対投票の理由を説明していただけますか?回答に対するフィードバックは、このサイトの品質を向上させるのに役立ちます。
Ben Cottrell 2017

4

あなたの元の質問は、他のほとんどの答えについてここで誤解を引き起こしたかもしれません。プロジェクト間で既存のコードをコピーするのではなく、異なるプロジェクトからの同じソースファイルを参照として含めるつもりなので、「重複するコード」の引数は、他の多くの引数と同様に無意味になります。

これは時々(常にではないが)賢明な手法であることに注意してください。実際、プロジェクト間で再利用したいすべてのソースファイルを1つの個別のインクルードフォルダーに入れると、すでにライブラリも構築されています。これは、バイナリライブラリではなく、ソースコードライブラリです。特にC ++では、テンプレートを使用して汎用ライブラリを作成する場合、単純なインクルードだけを必要とし、個別のリンクの準備を必要としない、ヘッダーのみのライブラリがあることも珍しくありません。

だからあなたの本当の質問は-ソースコードライブラリをいつビルドするのか、またはいつプリコンパイルされたバイナリライブラリを好むのか?この中で、このサイト上の古い答え、私は多分それはあなたを助け、ヘッダのみのLIBSのいくつかの長所と短所を議論しました。ソースコードライブラリの主な利点は、それらを使用するアプリケーションと同じランタイムフラグまたは互換性のあるコンパイラ/リンカーフラグでコンパイルする必要がないことです。欠点は、追加のコンパイル時間、およびソースコードへのアクセスを提供するための要件です(これは、明らかに、想定している「内部」プロジェクトの種類では問題ではありません)。


確かに、典型的な#includeディレクティブを介して必要なファイルを参照するだけの複数のプロジェクトに共通のソースコードライブラリを意味していました-あなたがそれを言うまで私はそれの用語を知りませんでした。今質問。あなたのリンクされた答えも非常に役に立ちます。
Andrew Murtagh 2017

@AndrewMurtagh:MichaelBorgwardtの回答をすぐに受け入れたという事実は私を驚かせました。彼が書いたのは彼または私の誤解のようです。
Docブラウン

よく彼は、複数のプロジェクトに共通するコードを単一のパッケージ(バイナリライブラリまたはソースコードライブラリのいずれか)にグループ化するときの最初の混乱を明確にしましたが、ソースの単一のディレクトリを持つことについて話していましたプロジェクト間で共有でき、必要に応じて各ファイルを各プロジェクトにコピーアンドペーストできないコード。
Andrew Murtagh 2017

2

他のコメンターがコードを複製してはならないと書いたとき、私はそれに同意します。しかし、あなたの場合、あなた(またはあなたが一緒に働く人々)は、他の場所で複製されていないコードのライブラリを作成しているようです。

この場合、私は時期尚早な一般化に対して警告します。コードの一部が再利用可能であると感じる場合がよくあります。ただし、2番目のユースケースがこのようなコードをどのように使用するかについての詳細がわからない場合、追加のケースでは実際には役立たない「再利用性」機能に余分な時間を費やしたり、間違っていると仮定したりすることは非常に簡単です。 2番目のケース。

1つのユースケースで「ライブラリ」を作成すると、見返りがなければ非常に費用のかかる練習になる可能性があります---これに何度も噛まれました。

費用の例:

  1. 「一般的な」ユースケースの検討に費やされた時間/エネルギー
  2. 「ライブラリ」を「クライアント」(独自のコード)に配布可能にするために費やされた時間
  3. 「ライブラリ」を次のユースケースと完全に一致させなくても、利用するという将来のプレッシャー

私の一般的なルールは次のとおりです。コードが必要な場所が少なくとも2つある場合を除いて、コードをライブラリにしないでください。


2
一部の開発者が使用している理由とほぼ同じ理由で、コードがすべて単一の> 2万行のソースファイルに含まれているのを見てきました。風変わりなネーミングや不適切なコメントと組み合わせると、コードを維持するよりも書き換えるほうが速いコードがすぐに得られます。
スティーブバーンズ

優れた点:私は確かに、保守可能で読みやすいコードを書くことについては反対していません。個別のファイル、適切な名前のメソッド/クラス、およびパッケージ構造は、すべて保守性の重要なコンポーネントです。私の要点は、「ライブラリ」のユースケースが1つしかない場合、ライブラリの作成+ライブラリの配布にかかるコストが非常に高くなることです。
サム

1
逆に、すべてのケースでライブラリをパッケージ化して配布する必要があるとは主張していません。コードがいつかライブラリになるかもしれないかのように記述して構造化することは、通常少しの努力に値し、コードが決してにならない場合でも利益をもたらすことが多いです。ライブラリとして配布。
スティーブバーンズ

1

ヘッダーと実装ファイルにアクセスでき、それらをソースツリーに含めてすべて一緒にコンパイルできるのに、内部ライブラリを内部アプリケーションにリンクするためだけに開発する必要があるのはなぜですか?

あなたが「私のソースツリーにそれらを含めるだけ」なら、あなたはコード複製しているからです

これの問題は、コードをコピーしたプロジェクトによって行われた改善(重要なバグ修正を含む)の恩恵を受けないこと、およびあなたが加えた改善の恩恵を受けないことです。

この問題は、最新バージョンのコードをソースツリーに定期的にコピーするだけで解決できると思うかもしれません。おそらくgitなどのサブモジュールを使用して自動化することもできます。ただし、互換性のないAPIの変更により、ビルドが常に中断されます。一方、ライブラリには「公式の」パブリックAPIがあり、開発者はクライアントと調整しないと変更できないことを知っています。

最後に、技術的な理由があるかもしれません-コードの一部をライブラリとして保持する必要があるので、オプションでロードしたり、必要に応じてロードおよびアンロードしたりできるため、機能が不要なときにメモリ使用量を削減できますか?


1
だから私が理解しているように、コードをライブラリに作成する主な理由は、コードが複製され、更新され、維持されないようにするために、コードがさまざまなプロジェクト(すべて内部で開発されている場合でも)で使用されるときです。別々に?また、単一のプロジェクトを開発するだけの場合は、ライブラリに何かを作成する必要はありません(後で別のプロジェクトで使用する予定がない限り)。
Andrew Murtagh 2017

@AndrewMurtagh:はい、それは私がそれを置く方法とまったく同じです。技術的な理由もあるかもしれませんが; 私はC / C ++開発にそれほど精通していません-おそらく、コードの一部をライブラリとして保持する必要があるので、オプションでロードしたり、必要に応じてロードおよびアンロードしたりできるため、機能が不要なときにメモリ使用量を削減できますか?
Michael Borgwardt 2017

それは共有ライブラリを通じて可能になると私は信じています。明確にしていただきありがとうございます。回答を承認します。
Andrew Murtagh 2017

過去10年間のほぼすべてのVCSは、外部参照またはサブモジュールをサポートしています。これにより、重複するコードとバグ修正の問題が解消されました。これらが有効な問題であるとまだ確信している場合、これらが実行可能な解決策ではない理由に関する詳細情報を含める場合があります。
Sirisian

メンテナンスも考えてください。1)libは独立して並行して保守できます。2)コードの置き換えは簡単ですか。3)小さなコードベースは、小さなチームにとって管理が容易であり、誰にとっても理解しやすいものです。4)市場投入までの時間が重要な場合は、より高速なビルドが望まれます。libsのコードは、パイプライン(IMO)で何度もコンパイルしないコードです。5)信頼性の高い再利用可能なコードです...作成しました;-)
Laiv

1

ソリューションの長期的なコストについて詳しく説明します。

明らかに、ライブラリをプロジェクトに追加すると、オーバーヘッドが発生します。これが最初の場合は上記のとおりです。ワークフローを変更する必要があり、インフラストラクチャやチームメンバーによっては(最初は)気に入らない場合もあります。そのため、よりコストがかからないため、ソリューションの利点は明白です。

ただし、プロジェクトが成長するにつれて、「疑似ライブラリ」のコストも増加します。Aアプリケーションと単体テスターが使用する「疑似ライブラリ」があると仮定します。cppをAに追加するたびに、両方のプロジェクトに追加する必要があります。追加しないと、リンクされません。

「疑似ライブラリ」が別の「疑似ライブラリ」によって使用されている場合はどうなりますBか?たくさんのプロジェクトに新しいcppを追加する必要があります。そして、B別のライブラリを使用するように切り替えたら?にAのみ依存するすべてのプロジェクトでcppsをから削除する必要がありBます。

実際のライブラリを使用する場合、これはすべて無料です。それで問題は、実際のライブラリへの移行を正当化するために必要なcppはいくつですか

しかし、待ってください。さらに多くの資料があります。開発者は、新しいcppを必要とするすべてのプロジェクトを探し出すというこの愚かな作業を嫌い、既存のファイルのどこかに自分のコード/クラスを追加します。これは、長期的には。

したがって、「疑似ライブラリ」を使用することは、モノリシックプロジェクトを分割するための最初のステップになる可能性がありますが、実際のライブラリをその利点を利用できるようにするために、それほど長く待つべきではありません。


0

しかし、ヘッダーと実装ファイルにアクセスでき、それらをソースツリーに含めてすべて一緒にコンパイルできるときに、内部ライブラリを内部アプリケーションにリンクするためだけに開発する必要があるのはなぜですか?

ライブラリが1つのアプリケーションでのみ使用される場合は、おそらくそれを別個のライブラリとして必要としません。

ライブラリは3500個のアプリケーションで使用されているなら、あなたは絶対にない別のライブラリとして、それを必要とします。

ライブラリにバグがあり、修正する必要がある場合はどうなりますか?または、法的または規制の変更が伴います。つまり、ライブラリの動作方法を変更する必要がありますか?

別のライブラリーにある場合は、ライブラリーを(場合によっては)修正し、再テストして再デプロイすると、すべてのアプリケーションで修正によるメリットが得られます。

各アプリケーションに対して「ローカル」であるのがソースコード内だけである場合は、すべてのアプリケーションを個別に変更、再ビルド、再テスト、および再デプロイする必要があります。これは、はるかに大きな(つまり、よりコストのかかる)演習です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.