私は常に [〜#〜] dry [〜#〜] の原則に厳密に従っています。怠惰な状態からコードを繰り返すたびに、そのコードを2か所で維持する必要があるときに後戻りします。
しかし、多くの場合、2つのプロジェクトが相互に参照できないことができない2つのプロジェクトで再利用する必要がある小さなメソッド(おそらく10行から15行のコード)を記述します。この方法は、ネットワーキング/文字列/ MVVMなどに関係している可能性があり、最初に置かれていたプロジェクトに固有ではない、一般的に有用な方法です。
このコードを再利用する標準的な方法は、再利用可能なコードの独立したプロジェクトを作成し、必要なときにそのプロジェクトを参照することです。これの問題は、理想的とは言えない2つのシナリオのうちの1つになってしまうことです。
.DLL
を作成する価値はありますか?base.common
という名前のプロジェクトを持っていました。これには、前述のようなフォルダー(ネットワーク、文字列操作、MVVMなど)が含まれていました。非常に便利でしたが、それを参照すると、必要のないすべての無関係なコードが不要にドラッグされました。だから私の質問は:
ソフトウェアチームは、プロジェクト間で小さなコードを再利用するにはどうすればよいですか?
私が特に関心を持っているのは、この分野でポリシーを持っている会社で働いていた人、または私と同じようにこのジレンマに個人的に遭遇した人です。
注:「プロジェクト」、「ソリューション」、「リファレンス」という言葉の私の使用は、Visual Studioでの.NET開発の背景に由来しています。しかし、この問題は言語とプラットフォームに依存しないと確信しています。
それらが本当に再利用可能なメソッド/クラスである場合、少数の「スイスアーミーナイフ」ライブラリーにそれらを書き込むことができます。私たちの会社ではこれを頻繁に行っています。それらをフレームワークライブラリと呼びます。
Framework.Data
-データベースクエリを操作するためのユーティリティ。Framework.ESB
-エンタープライズサービスバスとやり取りするための標準的な方法Framework.Logging
-統合ログシステムFramework.Services
-Webサービスと対話するためのユーティリティFramework.Strings
-高度な文字列操作/ファジー文字列検索などのユーティリティ.全部で、約12のライブラリがあります。実際に適切と思われるコードを配布することができるため、何百ものコードを作成したり、すべてを1つの巨大なアセンブリにダンプしたりする必要はありません。私たちのプロジェクトの一部だけがFramework.Data
を必要とするのはごくわずかですFramework.Strings
、つまり、消費者は特定のプロジェクトに関連するフレームワークの部分のみを選択できます。
それらが実際に単なるスニペットであり、簡単に再利用できる実際のメソッド/クラスではない場合は、コードスニペットとしてIDE(eg Visual Studio Codeスニペット )。私がこれまでに使用したことのあるチームには、共通のスニペットライブラリがあり、内部コードを使用して、誰もが標準のコーディングプラクティスに簡単に従うことができました。
私は多くの理由で受け入れられた答えに同意しません。
私の経験では、受け入れられた回答のような「その他」のライブラリを見つけたとき、それらは reinvent the wheel (または not invented here(NIH) )-aの言い訳です違反よりもはるかに大きな罪 Dont Repeat Yourself(DRY) 。
DRYに違反することは合理的な妥協である場合があります。密結合を導入するよりも優れています。再利用は、優れたオブジェクト指向設計と比較して二次的な懸念事項です。少し(つまり、少量を適用し、- つのルール )の複製は、スパゲッティコードベースよりも理解しやすいです。
多数の汎用ライブラリのアプローチは悪い例です。これは、アセンブリーの細かい粒度につながり、多すぎるアセンブリーは不良です。最近、社内のライブラリを24ライブラリから6ライブラリに減らしました。コンパイル時間を数分から約20秒に改善しました。 Visual Studioは、アセンブリの数が多いほど、読み込みが遅くなり、応答が遅くなります。ライブラリが多すぎると、コードをどこに配置するかが混乱します。少数の単純なルールを優先します。
.NET Frameworkの内容が十分でないのはなぜですか?フレームワークはかなり大きいです。すでに存在するものを再実装するコードを何度も目にしました。フレームワークが.Netフレームワークのギャップを埋めており、美的な理由で存在しないことを確認してください(たとえば、「ここでは.Netフレームワークが好きではない」またはおそらく 時期尚早の最適化 )。
アーキテクチャに別のレイヤーを導入すると、かなり複雑なコストがかかります。なぜレイヤーが存在するのですか?私は誤った再利用を見てきました。つまり、コードは社内フレームワークの上に構築されています。標準ライブラリの上に直接実装する方がはるかに効率的でした。
標準化されたテクノロジ(.Netフレームワークや一般的なサードパーティ/オープンソースライブラリなど)を使用すると、多くの場合、自分で構築した場合の技術的なメリットを上回るメリットがあります。これらのテクノロジーを知っている人材を見つけるのは簡単であり、既存の開発者はそれを学ぶためにより多く投資するでしょう。
私のおすすめ:
小さなコード(依存関係のない単一のクラスなど)の場合、コードをコピーしてプロジェクトに貼り付ける傾向があります。これはDRYの違反のように聞こえ、私はそれが時々あり得ることを認めます。しかし、長期的には、いくつかの理由により、ある種の大規模なマルチヘッドのコモンズプロジェクトよりもはるかに優れています。
まず、コードを手軽に使用できるほうが簡単です。特に、ビルドやデバッグの際に便利です。
次に、必ず、そのプロジェクトの一般的なコードに少し調整を加えます。ソースのローカルコピーがある場合は、Tweakを作成して、1日で呼び出すことができます。共有ライブラリがある場合は、そのライブラリを微調整して、他のすべてのアプリを壊したり、バージョン管理の悪夢を作成したりしないようにすることができます。
したがって、それ自体の名前空間では十分でない場合は、プロジェクトの適切なビットにプッシュして、1日と呼ぶ傾向があります。
あなたが説明する2番目の解決策はそれほど悪くありません。 .NETでは、単一のクラスを使用している場合でも、GACからアセンブリも参照します。 「無関係なコードをドラッグする」ことは、あなたが考えているような問題ではありません。この場合、少なくとも関連するメソッドとクラスを異なる名前空間に整理しておくことが重要です。さらに、API設計の優れたプラクティスを適用して、このソリューションが混乱しないようにする必要があります。
非常に小さなコードに関しては、次のアプローチが一般的なプロジェクトの良い補足になると思います。それらを異なるソリューションで複製できるようにします。それらをベストプラクティスのように扱います。文書化してチームに伝えます。
私はこれまで、この種のことが問題であり、採用される2番目のオプションである「エンタープライズ」環境でのみ働いていました。ほとんどの場合、アプリケーションのフットプリントに制約がなかったため、問題なく動作しました。
ただし、先週、独自のNugetサーバーを実行している新興企業と過ごしたので、これを実行可能な代替案として提案する傾向があります。もちろん、私が明らかにすることを期待している問題は発見可能性に関係するでしょう。
プロジェクトが適切にきめ細かく、名前空間が賢明である場合、これが場所で人気のあるアプローチになっていることがわかります。
私は最近これについて考えました、そして私に起こったのはこれまで述べられてきた一般的な方法の大きなライブラリでしたが、ひねりを加えました。ライブラリプロジェクトを使用すると、コンパイル時に BusyBoxプロジェクト のように含まれる要素を構成できます。そのアプローチでは、キッチンシンクスタイルのライブラリリポジトリを作成できますが、コンパイル時に必要なツールのみを取得できます。
GitHubには、コードスニペットを保存するためのかなり便利なツールがあります https://Gist.github.com/
これは、スニペットをgitリポジトリとして保存し、非公開にしたり、他の人とスニペットを共有したりできます。
チーム/プロジェクト/会社の規模によっては、既に何らかの形で環境に組み込まれていない限り、これを効率的に実行するのはかなり難しく、見つけたすべてのソリューション(実装する場合)には費用がかかります。 (それはあなたをより安全にするかもしれませんが、あなたは簡単に測定することができないでしょう)。あなたはそれが価格の価値があるかどうかを確認する必要があります。また、再利用可能なソリューションは抽象的になる傾向があり、多くの場合、多くの状況に適合しますが、最適ではないことに注意してください。
いずれにせよ、複数の人が作成したコードに対してこれを行う場合は、最初は全員の意識と協力が必要です。これには、開発者と管理者が含まれます。
次に、これを実行するスコープを確認する必要があります。チーム?事業?部門?会社?答えに応じて、DLLを調整する粒度と同様に、そのようなソリューションに組み込むコードの種類は異なります。これを決定したら、誰かが(できればアイデアに熱意を持って-できればあなたは?)座って、これに何らかの構造を取り入れる必要があります。
ただし、そのようなDLLを作成するだけでは、トリックを実行するには不十分です。それらを有用なものにするためには、それらを(ユーザーと貢献者に)宣伝し、他のソフトウェアと同様に維持する必要があります。これは、通常、誰かに長い間担当する必要があることを意味します。また、信頼性の高いドキュメントも必要です。そのため、メンテナンスも必要になります。運と協力があれば、いくつかのベストプラクティスが得られるかもしれませんが、関係するチームの規模と数に応じて、独自のプロジェクトに簡単に発展させることもできます。そのためには、まだ管理サポートが必要です。
私は多くの問題に遭遇しました、そして私が好む解決策はgithub/pubic Web対応リポジトリにコードを投稿することです。それは多くの問題を解決します-
私がお勧めすることの1つは、スニペットをどこに置いても、使用する前に常にGoogleのものを使用することです。物事は常に変わります。 保存されたスニペットは時間を節約するだけでなく、自己満足を育む。
私の会社はイントラネットローカルWebサービスを使用しています。一般的な内部Webサービスとして設定されているいくつかのWebサービスがあり、別のプロジェクトがサービスの1つにアクセスする必要がある場合、定義されたインターフェースでhttpリクエストを送信します。イントラネット上にあり、同じサーバーファームに格納されているため、これらの要求は非常に高速です。
明らかに、これはインターネットアプリでのみ機能します(同じローカルネットワーク上ではミリ秒単位でのみ機能します)が、いくつかの本当に素晴らしい利点があります。
テストと一緒にこれらすべての小さなメソッドを保存する別のプロジェクト「ユーティリティ」があります。
プロジェクトにユーティリティが必要な場合は、「リンクとして追加」で必要なメソッドを使用してソースファイルを追加するだけです。
これは、実行時の依存関係が追加されていないことを意味します(インクルードされるファイルに必要な場合を除く)。
システムはうまく機能していますが、他のすべてのシステムと同様に、ユーティリティとは何かについての専門知識が必要です。高いテストカバレッジを要求することは私たちにとってはうまくいき、テストは使用法のドキュメントとしても優れています。発見はまだ私たちにとって未解決の問題です。
ユーティリティプロジェクトの複雑さの1つは、アイテムの表示レベルを決定することです。経験則では、メソッドは内部で、データ構造はパブリックである必要があります。
私は最近このサービスを思いつきました:Snip2Code( http://www.snip2code.com )。
これは、完全にライブラリではなくスニペットのみをチームと共有する興味深い方法です。他のプロジェクトで参照する必要のある一般的なライブラリを作成するという通常のポイントを打破します。私の意見では、これは貴重なビジョンです。
さらに、共通ライブラリの使用が適用されなかった場合のシナリオはたくさんあります。たとえば、シングルトン、ストラテジー、オブザーバーなどのデザインパターンを考えてみましょう。このようなパターンをサポートするライブラリを作成できますが、それでも100%カバーすることはできません。
本当の必要性は、チーム間で共通の慣行を共有するツールを持つことです。私はGithubの要旨を使用しようとしましたが、それらの検索(本当に貧しい)と、自分のチームだけで共有することはできず、他のメンバーとは共有できないという事実に悩まされています...
(免責事項:私はSnip2Codeの創設者の1人であり、私は-共同創設者と一緒に-少し前に同じ考え方でいました:これが私たちがこのプロジェクトを開始することにした理由です!!)