恥ずかしいことに、数十年前のチーム環境で、そのような名前の「共通」ライブラリを導入しました。私は、ほんの数か月のうちに、ゆるやかに調整されたチーム環境で何が起こるかについて、当時のダイナミクスを本当に理解していませんでした。
私がそれを紹介したとき、私はそれを明確にし、それが日常的に有用であると私たち全員が同意するもののためであること、それがミニマリストライブラリであることを意図していること、そしてライブラリは標準ライブラリを使用して、新しいプロジェクトにできるだけ簡単に展開できるようにします。当時の私の考えは、私たちの特定の分野で日常的に有用であることがわかったもののための、標準ライブラリへの私たち自身の小さな拡張だと思っていました。
そして、それは十分に始まりました。私たちcommon/math*
は線形代数で重いことが多いコンピューターグラフィックスで作業していたため、私たちは毎日日常的に使用するルーチンの数学ライブラリ()から始めました。そして、私たちはしばしばCコードと相互運用してfind_index
いたので、次のような便利なユーティリティ関数に同意しました。std::find
C ++では、C関数の仕組みを模倣したイテレータではなく、シーケンスで見つかった要素にインデックスを返します-この種のもの-少し折ec的ですが、ミニマリストであり、誰もが使い慣れた実用的なままで十分に広く使用されています、そして、すぐに親しむことは、「共通」または「標準」であるものを作成しようとする際に見られるように、非常に重要な基準です。採用と毎日の使用。
しかし、時間の経過とともに、人々が個人的に使用するものを追加するようになったため、ライブラリの設計意図は私の指から外れました。そして、後に誰かが一般的なGL関連ルーチンのOpenGLに依存する関数を追加し始めました。さらにQtを採用し、Qtに依存するコードの追加を開始したため、すでに共通ライブラリは2つの外部ライブラリに依存していました。ある時点で誰かが私たちのアプリケーション固有のシェーダーライブラリに依存する一般的なシェーダールーチンを追加し、その時点でQt、OGL、および私たちのアプリケーション固有のシェーダーライブラリを持ち込まずに新しいプロジェクトにデプロイすることさえできませんでしたプロジェクトの重要なビルドスクリプト。それで、この折this的な相互依存の混乱に変わりました。
しかし、このライブラリに入れるべきものとすべきでないものを議論することで、「共通」であるという非常に厳しいラインルールを設定しないと、「共通」と見なされるものは非常に主観的な考えになりやすいことも発見しました誰もが毎日役に立つと思うもの。規格のゆるみとそれは、誰もが日常的に有用だと思うものから、単一の開発者が他の誰かに有益である可能性のあるものにすぐに劣化し、その時点でライブラリは折fast的な混乱に本当に劣化します。
しかし、さらにその点に達すると、一部の開発者は、プログラミング言語が好きではないという単純な理由で物事を追加し始めることができます。彼らはforループや関数呼び出しの構文が気に入らないかもしれません。その時点で、ライブラリは言語の基本的な構文と戦っているものでいっぱいになり始め、実際にはそうではない簡単なコードの数行を置き換えます。そのような速記を導入した開発者にしか馴染みのない、エキゾチックなコードの簡潔な行にロジックを複製します。次に、そのような開発者は、そのような速記を使用して実装された共通ライブラリに機能を追加し始めるかもしれません。その時点で、共通ライブラリの重要なセクションがこれらのエキゾチックな速記と織り交ぜられ、それを導入した開発者には美しく直感的に見えるかもしれませんが、くて外国人で、他の人には理解しにくいでしょう。そして、その時点で、「共通」と「なじみのない」は正反対の考えであるため、真に「共通」なものを作成する希望は失われることを知っていると思います。
そのため、少なくとも大雑把に調整されたチーム環境には、あらゆる種類のワームの缶があり、「一般的に使用されるもの」と同じくらい広く、一般化された野望を持つライブラリがあります。そして根本的な問題は何よりも緩い調整であったかもしれませんが、数学ルーチンなどを提供することを目的としたライブラリのような、より特異な目的に役立つことを目的とした少なくとも複数のライブラリは、おそらくその点でそれほど劣化しません「共通」ライブラリとしての純度と依存関係を設計します。ですから、振り返ってみると、より明確な設計意図を持つライブラリの側でエラーを起こした方がはるかに良いと思います。また、長年にわたって、目的の狭さと適用可能性の狭さは根本的に異なる考えであることを発見しました。
また、私は少なくとも少し非実用的であり、美学についてはあまり気にしないかもしれませんが、ライブラリの品質(そしておそらく「美しさ」)についての私の考えを理解する方法は、その最も弱いリンクによって判断されます世界で最も食欲をそそる食べ物を見せてくれたのに、同じ皿の上に腐ったものを入れて本当に悪臭がするのと同じように、その最強は、皿全体を拒否する傾向があります。そして、あなたがその点で私のようであり、あらゆる種類の追加を「共通」と呼ばれるものとして誘うものを作るなら、あなたはあなたがその横に何かが腐っているその類推的なプレートを見ていることに気付くかもしれません。それで、同様に、図書館が組織され、命名され、文書化されていれば良いと思います。時間が経つにつれて、ますます多くの追加を招待します。確かに私はあちこちで腐ったものを作成しているので、それはあなたの個人的な作品にも当てはまります。それが最大のプレートに追加されていない場合、それははるかに「汚染」されます。ものを小さく非常に特異なライブラリに分離することは、すべてを結合し始めるのがはるかに不便になるという単なる美徳によってのみ、コードをより良く分離する傾向があります。
コードの重複排除は長年にわたって私に打ち込まれてきましたが、今回はそれを試してみるべきだと思います。
あなたのケースで私が提案できるのは、コードの重複排除を簡単に始めることです。十分にテストされていない、エラーが発生しやすいコードの大きなスニペットまたはこの種のコードをコピーして貼り付けたり、将来変更を必要とする可能性のある非自明なコードを大量に複製したりするつもりはありません。
しかし、特に「共通」ライブラリを作成しようと考えている場合は、広く適用可能で、非常に再利用可能なものを作成することを望んでいると思います。 、場合によっては、このとらえどころのない品質を達成するために、いくつかの複製が必要になる場合があります。複製は実際には分離メカニズムとして機能する可能性があるためです。ビデオプレーヤーをMP3プレーヤーから分離したい場合、少なくともバッテリーやハードドライブなどを複製する必要があります。彼らはこれらのことを共有することはできませんし、分割できないため互いに独立して使用することはできません。その時点で、MP3を再生するだけなら、人々はもはやデバイスに興味を持たないかもしれません。しかし、これら2つのデバイスを分割した後しばらくすると、MP3プレーヤーが、ビデオプレーヤーとは異なるバッテリー設計または小さいハードドライブの恩恵を受けることができるかもしれません。この相互依存デバイスを2つの別個の独立したデバイスに分割できるようにする複製として最初に開始されたものが、後で冗長でなくなった設計と実装をもたらすことがあります。
ライブラリを使用するものの観点から物事を検討する価値があります。実際に使いたいですかコードの重複を最小限に抑えるライブラリ?たぶん、他のライブラリに自然に依存するので、あなたはそうしないでしょう。そして、他のライブラリはコードの重複を避けるために他のライブラリに依存する可能性があります。オーディオファイルのロードや再生などの基本的な機能を取得するために50の異なるライブラリをインポート/リンクする必要が生じるまでは、非常に扱いにくくなります。一方、そのようなオーディオライブラリが意図的にあちこちでいくつかのことを複製してその独立性を達成することを選択した場合、新しいプロジェクトでの使用が非常に簡単になり、チャンスがあるため、ほとんど更新する必要がなくなる可能性があります依存する外部ライブラリが変更された結果、オーディオライブラリが必要とするものよりもはるかに一般化された目的を達成しようとしている可能性があるため、変更する必要があります。
そのため、ライブラリを分離して独立させるために、意図的に少し複製することを意識して選択する価値があります(意識的に、怠ofからではなく、実際には勤勉からではありません)安定性(求心性結合がなくなります)。あるプロジェクトから次のプロジェクトまで、そして何年にもわたって可能な限り最も再利用可能なライブラリを設計したい場合、その範囲を最小限に抑えることに加えて、ここで少し複製することを実際に検討することをお勧めします。そして、ユニットテストを自然に書き、それが実際に徹底的にテストされ、それが何をしているのか信頼できることを確認してください。これは、1つのプロジェクトをはるかに超えるポイントに一般化するために本当に時間をかけたいライブラリ専用です。