プロジェクト間でコードの小さなスニペットを共有するためのベストプラクティス


102

私は常に仕事で厳密にDRYの原則に従うようにしています。怠inessな状態からコードを繰り返すたびに、後でそのコードを2か所で維持する必要が生じたときに戻ってしまいます。

しかし、多くの場合、互いに参照できない 2つのプロジェクトで再利用する必要がある小さなメソッド(10〜15行のコード)を記述します。この方法は、ネットワーク/文字列/ MVVMなどに関連するものである可能性があり、元々のプロジェクトに固有ではない一般的に有用な方法です。

このコードを再利用する標準的な方法は、再利用可能なコード用に独立したプロジェクトを作成し、必要なときにそのプロジェクトを参照することです。これに伴う問題は、2つの理想的ではないシナリオのいずれかになってしまうことです。

  1. 最終的に、数十/数百の小さなプロジェクトになります-それぞれが再利用する必要のある小さなクラス/メソッドを収容します。.DLLほんの少しのコードだけでまったく新しいものを作成する価値はありますか?
  2. 関係のないメソッドとクラスのコレクションが増え続ける1つのプロジェクトになります。このアプローチは、私が以前働いていた会社がやったことです。彼らには、base.common前述のようなネットワーク、文字列操作、MVVMなどのフォルダーを持つプロジェクトがありました。それは信じられないほど便利でしたが、不要なすべての無関係なコードを不必要にドラッグして参照しました。

だから私の質問は:

ソフトウェアチームは、プロジェクト間で少量のコードを再利用するのに最適な方法を教えてください。

特に、この分野でポリシーを持っている会社で働いている人や、私のように個人的にこのジレンマに直面している人に興味があります。


注:「プロジェクト」、「ソリューション」、および「参照」という言葉の私の使用は、Visual Studioでの.NET開発の背景から来ています。しかし、この問題は言語とプラットフォームに依存しないと確信しています。


21
+1。.NETで作業している誰かに、DLL参照を介して無関係なコードをドラッグすることを心配しているユーモアの要素があると思いますが。
-JDB

2
@ColeJohnson .NET自体は大きなリファレンスです!おそらく私が自分で作成するDLLよりもはるかに大きいでしょう。
ジョージパウエル

2
わかった。ただし、.NETのJITコンパイラは、必要なメソッドをRAMにロードするだけです(呼び出されたとき)
Cole Johnson

1
本当です。製品を使用したい人に.NETフレームワーク全体を配布する必要がありますが、大きなプロジェクトや複雑なソリューションの管理はさらに困難です。
ジョージパウエル

回答:


75

それらが本当に再利用可能なメソッド/クラスである場合、少数の「スイスアーミーナイフ」ライブラリに書き込むことができます。私たちの会社ではこれを頻繁に行っています。フレームワークライブラリと呼びます。

  • Framework.Data -データベースクエリを操作するためのユーティリティ。
  • Framework.ESB -エンタープライズサービスバスとやり取りするための標準的な方法
  • Framework.Logging -統合ログシステム
  • Framework.Services -Webサービスと対話するためのユーティリティ
  • Framework.Strings -高度な文字列操作/ファジー文字列検索などのユーティリティ
  • ...

全部で、約12ほどのライブラリがあります。適切にコードを配布することができます。そのため、数百になったり、すべてを1つの巨大なアセンブリにダンプしたりする必要はありません。このアプローチが適しているのは、私たちのプロジェクトの一部のみが必要でFramework.Dataあり、少数のプロジェクトのみが必要Framework.Stringsになるため、消費者は特定のプロジェクトに関連するフレームワークの部分のみを選択できるからです。

それらが実際に単なるスニペットであり、簡単に再利用できる実際のメソッド/クラスではない場合、コードスニペットとしてIDEに配布するだけです(例:Visual Studio Code Snippets)。過去に作業したチームには共通のスニペットライブラリがあり、誰もが内部コードを使用して標準のコーディングプラクティスに従うことが容易になりました。


4
+1これも私のアプローチです。2つ以上の側面からのものを扱うコードをどこに置くかをどのように決めたかを知りたい たとえば、IPAddressToString。そして、これらのライブラリが相互に使用できるようにするかどうか。例えば、サービスやデータは、おそらく...ログから多くの恩恵を受けることができます
マージャンVenema氏

5
@MarjanVenema横断的なコードの場合、どのコンシューマーがこのメソッドをより有用であるかによって異なります。のためにIPAddressToString、ネットワークプロトコルを扱う消費者はそれを使用しなければならない可能性が高いですが、文字列を多くいじる消費者はIPアドレスをまったく気にかけないかもしれません。それはたぶんむしろネットワークパッケージで終わるでしょうFramework.Strings
pswg

@MarjanVenema私たちは相互依存関係を避けようとしています。当社のサービスおよびデータフレームワークは、それ自体ではロギングを行わないように記述されていますが、消費者が適切なロギングコードを記述しやすくします。フレームワークライブラリは、相互に参照することを許可されていますが、拡張機能によってのみ許可さFramework.Logging.Gibraltarれています。たとえば、ロギングシステムへの特定のアドオンです。
pswg

5
+1これらのフレームワークライブラリを使用して、内部のNuGetリポジトリ(ネットワークフォルダーと同じくらい簡単)に展開すれば、それを管理する優れた方法が得られます。
スティーブンエバーズ

2
@SteveEvers私は実際にその設定に取り組んでいます。:P
pswg

21

私は多くの理由で受け入れられた答えに同意しません。

私の経験では、受け入れられた答えのような「その他」のライブラリを見ると、車輪再発明する言い訳になります(またはここでは発明しません(NIH))- Dont Repeat Yourself(DRY)に違反するよりもはるかに大きな罪です。

DRYに違反することは合理的な妥協である場合があり、密結合を導入するよりも優れています。再利用は、優れたオブジェクト指向設計と比較して、二次的な関心事です。スパゲッティコードベースよりも少し(少しだけ意味します。3つ規則を適用します)の複製は理解しやすいです。

多数の汎用ライブラリのアプローチは、悪い例を示しています。アセンブリのきめ細かい細分化につながり、アセンブリが多すぎると問題が発生します。最近、社内のライブラリを24のライブラリから6つのライブラリに減らしました。コンパイル時間を数分から20秒に改善しました。Visual Studioは、アセンブリが多いほど読み込みが遅くなり、応答性が低下します。ライブラリが多すぎると、コードの配置場所に関する混乱も生じます。より少ない、よりシンプルなルールを好む。

.Net Frameworkのものが十分ではないのはなぜですか?フレームワークはかなり大きいです。すでに存在するものを再実装するコードを見てきました。フレームワークが.Netフレームワークのギャップを埋めており、審美的な理由だけで存在していないことを本当に確認してください(たとえば、「ここでは.Netフレームワークが気に入らない」またはおそらく早すぎる最適化

アーキテクチャに別のレイヤーを導入すると、かなり複雑なコストがかかります。なぜレイヤーが存在するのですか?誤った再利用を見てきました。つまり、コードは社内のフレームワークの上に構築されているということです。標準ライブラリの上に直接実装する方がはるかに効率的でした。

標準化されたテクノロジー(.Netフレームワークや人気のあるサードパーティ/オープンソースライブラリなど)を使用すると、多くの場合、自分で構築した場合の比較的な技術的利益を上回る利点があります。これらの技術を知っている人材を見つけるのは簡単であり、既存の開発者はそれを学ぶためにもっと投資します。

私の推奨事項:

  • このコードを共有しないでください。
  • それがまとまりのある目的を持っている場合、泥のデザインパターンのボールを使用しないで、新しいライブラリを作成します。
  • 可能な場合は、既存のサードパーティライブラリを再利用します。
  • コードを配置する場所についてのより単純なルールを使用して、より少ないアセンブリを優先します。

1
利用可能な場所でオープンソースライブラリを使用することには、大きなメリットがあります。改善点があれば、コミュニティに共有できます。たとえば、.Net MSでは、一般的なシナリオに適したツールセットを提供するEnterpriseLibrary(現在はOpen Source)が公開されています。そこで改善できるものを見つけてください。誰もが利益を得る!
グレナトロン

2
ここで受け入れられた答えに不一致は本当にありません:-)。「アセンブリの数を減らし、コードを配置する場所に関するルールを簡素化する」ことは、受け入れられている答えと矛盾しません。答えはまた、合理的と思われる限り多くの異なるアセンブリのみを使用することを推奨しています。
sleske

5年後Microserviceガイダンスもこの練習に収束した:medium.com/standard-bank/...
デイブ・ヒリアー

11

小さなコード(依存関係のない単一のクラスなど)の場合は、コードをコピーしてプロジェクトに貼り付けるだけです。これはDRYの違反のように聞こえます。しかし、長期的には、いくつかの理由で、ある種の大規模なマルチヘッドコモンズプロジェクトを持つよりもはるかに優れています。

まず、特にものをビルドしてデバッグするときに、コードを手軽に使用する方が簡単です。

第二に、常にそのプロジェクトの共通コードを少し調整したいと思うでしょう。ソースのローカルコピーを取得している場合は、微調整して1日で呼び出すことができます。共有ライブラリがある場合は、そのライブラリを調整し、他のすべてのアプリを壊したり、バージョン管理の悪夢を作成したりしないようにしてください。

したがって、それが独自の名前空間で十分に機能しない場合は、プロジェクトの適切な部分にプッシュして、1日と呼ぶ傾向があります。


5
このアプローチには同意しません。私は小さなコードの管理に伴うメンテナンスの問題に感謝していますが、@ pswが示唆しているように、それらすべてからいくつかの共通ライブラリを作成できると主張します。微調整を加えたコードのコピーを複製することは、トラブルを求めています。仮定が行われ、バグ修正が見落とされます。
アンドリューTフィンネル

2
-1(答えに)。誰もが自分のバージョンのプログラムの独自のコピーを持っている方が簡単です。これがソフトウェアが80年代に開発された方法です。それ以来、長期的に見て、これが混乱につながることを学びました。人々が自分の仕事についてもっと多くのことを伝えなければならないので、正しいことをして共通のライブラリを持つことはより困難です。まあ、彼らはすべきです。
マイケルデュラント

3
+1-頻繁に使用したくない場合でも、このアプローチに言及する価値があると思います。一部のスニペットはデザインパターンに似ています-emを再利用しますが、どこでもわずかに異なる方法で、おそらく異なる言語で使用し、おそらく変更する必要があります。また、広く再利用されたライブラリは、APIの変更が非常に危険であるという点で柔軟性がありません。最後に、このアプローチをフォールバックとして使用すると、実験的なものを少し長くすることで共有ライブラリの品質が向上します。
イーモンネルボンヌ

6

あなたが説明する2番目の解決策はそれほど悪くはありません。.NETでは、単一のクラスを使用する場合でも、GACからアセンブリを参照します。「無関係なコードのドラッグ」は、あなたが思うかもしれない問題ではありません。この場合、少なくとも関連するメソッドとクラスを異なる名前空間できれいに整理することが重要です。さらに、このソリューションが混乱するのを防ぐために、API設計の優れたプラクティスを適用する必要があります。

非常に小さなコードの場合は、次のアプローチが一般的なプロジェクトの良い補足になると思います。異なるソリューションでそれらを複製できるようにします。ベストプラクティスのようにそれらに対処します。文書化してチームに伝えます。


1
非標準ライブラリの場合を除き、これは、1回(または数回)の使用のために大きなアセンブリを出荷する必要があることを意味します。とにかく利用できるので、これは標準的なものにとっては問題ではありませんが、良い方法で分割できるなら、大規模だがほとんど使用されていないアセンブリの出荷は絶対に避けたいです。
2013年

6

この種のことが問題であり、採用されるたびに2番目の選択肢になるたびに、「エンタープライズ」環境で働いたことがあります。アプリケーションのフットプリントに制約がなかったため、ほとんどの部分で問題なく動作しました。

しかし、自分のNugetサーバーを実行している新興企業と先週を過ごしたので、これを実行可能な選択肢として提案したいと思います。もちろん、私が浮かび上がると予想される問題は、発見可能性に関するものです。

プロジェクトが適切にきめ細かく、名前空間が適切である場合、これは場所で人気のあるアプローチになることがわかります。


それらはどのような意味で発見できないと期待していますか?私たちは、そのようにして、多数の、そして成長しつつあるnugetパッケージを使用します。私たちが抱えている最大の問題は、バージョン管理と依存関係の管理です。
pdr

ああ、はい。それらも。検出可能性に関する問題では、特定の機能を備えた小さなパッケージが十分な数ある場合、それぞれをカタログ化(および検索)することがより難しくなる可能性があります。たとえば、チームはどのパッケージにさまざまな機能が含まれているかをどのように知らせるのですか?(ここでヌジェの検索無知を表示)
コフィサルフォ

ああなるほど。ええ、あなたは間違いなく説明に好きなものを入れることができ、それが検索可能になりますが、問題がないようにパッケージを十分にグループ化したと思います。
pdr

@sarfeast Nugetサーバーへのリンクを共有し、それについて少し教えていただけたら嬉しいです。
ハンスピーターシュトルー

6

私は最近これについて考えました。そして、私に起こったのは、これまで述べてきたように、ひねりを加えた一般的なメソッドの大きなライブラリでした。ライブラリプロジェクトを使用すると、コンパイル時にBusyBoxプロジェクトのようなものを含めるように構成できます。このアプローチを使用すると、キッチンシンクスタイルのライブラリリポジトリを作成できますが、コンパイル時に必要なツールのみを取得できます。


5

GitHubには、コードスニペットhttps://gist.github.com/を保存するための非常に便利なツールがあります

スニペットをGitリポジトリとして保存します。Gitリポジトリは非公開にしたり、スニペットを他の人と共有するために使用できます。


3

チーム/プロジェクト/会社の規模によっては、環境に何らかの形で既に組み込まれていない限り、これを効率的に行うのはかなり難しくなり、(実装する場合)見つけるすべてのソリューションにはいくらかお金がかかります。(もっと安全かもしれませんが、簡単に測定することはできません)。価格に見合うかどうかを確認する必要があります。また、再利用可能なソリューションは抽象的になる傾向があり、多くの場合、最適ではなく多くの状況に適合することに留意してください。

いずれにせよ、複数の人が作成したコードに対してこれを行いたい場合は、最初は全員の認識と協力が必要です。これには開発者とマネージャーが含まれます。

次に、これを行うスコープを確認する必要があります。チーム?事業?部門?会社?答えに応じて、そのようなソリューションに入れるコードの種類は異なり、dllを調整する粒度も異なります。これを決定したら(おそらくアイデアに対する熱意があれば-あなた?)座って、これに何らかの構造を入れ始める必要があります。

ただし、このようなdllを作成するだけでは十分ではありません。それらを有用にするためには、それらを(ユーザーと貢献者に)宣伝し、他のソフトウェアと同様に維持する必要があります。これは通常、彼らに長い間責任を負わせる必要があることを意味します。信頼性の高いドキュメントも必要になりますが、メンテナンスも必要になります。ある程度の幸運と協力があれば、いくつかのベストプラクティスが得られる可能性がありますが、関与するチームの規模と数に応じて、独自のプロジェクトに簡単に発展させることができます。そのためには、引き続き管理サポートが必要です。


3

私は多くの問題に遭遇しましたが、私の好みの解決策は、github / pubic Web対応リポジトリにコードを投稿することです。それは多くの問題を解決します-

  1. 簡単にアクセスでき、簡単に共有できます。cvs / svn / enterprise-reposは、プロジェクトを複数のIDEワークスペースにチェックアウトすることを意味し、小さなコードスニペットを参照するためだけにワークスペースまたはコンピューターを切り替える必要がある場合があります。
  2. これらのコードスニペットはプロプライエタリ/分類されたコードではなく、公開されている知識のバリエーションであると仮定すると、githubのような公開リポジトリに投稿すると、他の人がそれを見て、貢献することさえできます。
  3. パブリックドメインに自分の名前で何かを投稿すると、評判が高まります。プログラマーとしてのあなたの能力を反映しているので、物事を再確認して更新します。
  4. アップデート。リポジトリでコードスニペットを維持することに関することは、スニペットが長い間使用されていない場合、古くなる可能性があります(古いapis / libsを含む)。例-ファイルを読み取るためのJavaコードスニペット。2009年にこれを行う最善の方法を見つけたかもしれませんが、2014年にはすべてを変更する新しいファイルAPIが登場します。あなたのスニペット?まだ2009年に立ち往生しています。公開レポでは、あなた(弾丸3のせい)、チームメイト、または一般的なプログラマー集団のメンバーのいずれかによって更新されます。あなたは長い間間違えていたかもしれません。

私がお勧めすることの1つは、スニペットをどこに保管するかに関係なく、使用する前に常にグーグルを片付けることです。物事は常に変化します。節約されたスニペットは時間を節約するだけでなく、自己満足を生み出します。


2

これらの小さなメソッドをすべてテストと一緒に保存する別のプロジェクト「ユーティリティ」があります。

プロジェクトに何らかのユーティリティが必要な場合、「リンクとして追加」を使用して必要なメソッドでソースファイルを追加するだけです。

これは、実行時の依存関係が追加されていないことを意味します(含まれているファイルに必要な場合を除く)。

このシステムはうまく機能していますが、他のすべてのシステムと同様に、ユーティリティとは何かに関するディシプリンが必要です。高いテストカバレッジを要求することは私たちにとってうまく機能し、テストも優れた使用法のドキュメントです。発見はまだ私たちにとって未解決の問題です。

ユーティリティプロジェクトの複雑さの1つは、アイテムの可視性レベルを決定することです。経験則では、メソッドは内部であり、データ構造はパブリックでなければなりません。


2

私の会社はイントラネットローカルWebサービスを使用しています。共通の内部Webサービスとして設定されたいくつかのWebサービスがあり、別のプロジェクトがサービスの1つにアクセスする必要がある場合、定義済みのインターフェースを使用してhttpリクエストを送信します。同じサーバーファームにあるイントラネット上にあるため、これらの要求は非常に高速です。

明らかに、これはインターネットアプリでのみ機能します(同じローカルネットワーク上でミリ秒単位でのみ機能します)が、いくつかの本当に素晴らしい利点があります。


0

私は最近このサービスを思いつきました:Snip2Code(http://www.snip2code.com)。

これは、スニペットのみ(ライブラリ全体ではない)をチームと共有する興味深い方法です。他のプロジェクトで参照する必要のある共通ライブラリを作成することは、通常のポイントを破ります。私の意見では、これは貴重なビジョンです。

さらに、共通ライブラリの使用が単純に適用されないシナリオが多数あります。たとえば、シングルトン、ストラテジー、オブザーバーなどのデザインパターンを考えてみましょう。そのようなパターンをサポートするライブラリを作成できますが、それでも100%のカバレッジはありません。

本当の必要性は、チーム間で共通のプラクティスを共有するツールを持つことです。私はGithubの要点を使用しようとしましたが、それらの検索(本当に貧しい)と、チーム間でのみ共有でき、他の人とは共有できないという事実に固執しています...

(免責事項:私はSnip2Codeの創設者の1人であり、共同創業者と一緒に-少し前にあなたとまったく同じ考え方でした:これが、このプロジェクトを開始することにした理由です!)

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