私はコピーアンドペーストをしているので、私は悪いプログラマーでした。たとえば、データベースに接続してレコードセットを取得するたびに、前のコードをコピーして編集し、datagridviewを設定するコードをコピーして編集します。フレーズコードの再利用については知っていますが、実際には使用していません。データベースコードとdatagridviewコードをコピーして貼り付ける必要がないように、コードの再利用を利用するにはどうすればよいですか。
14 に答える
コードの再利用の本質は、さまざまな入力を受け入れることができるように、一般的な操作を実行してパラメーター化することです。
謙虚なprintf
例を考えてみましょう。printf
あなたが持っていなかった、そして持っていたwrite
、または類似のものだけを想像してみてください:
//convert theInt to a string and write it out.
char c[24];
itoa(theInt, c, 10);
puts(c);
今、これは毎回書く必要があり、実際にはバグのようなものです。そのため、一部の賢いプログラマーは、これにうんざりしていると判断し、より優れた関数を作成しました。
printf("%d", theInt);
printf
可変個引数とフォーマット文字列のように凝ったものにする必要はありません。次のような単純なルーチンでも:
void print_int(int theInt)
{
char c[24];
itoa(theInt, c, 10);
puts(c);
}
トリックニッキーを行います。このように、print_int
常にstderrに出力するように変更する場合は、次のように更新できます。
void print_int(int theInt)
{
fprintf(stderr, "%d", theInt);
}
そして、すべての整数が魔法のように標準エラーに出力されるようになりました。
次に、その関数と、作成した他の関数をライブラリにバンドルすることもできます。これは、プログラムにロードできるコードのコレクションにすぎません。
コードの再利用の慣習に従うと、接続するデータベースさえあります。誰かがレコードをディスクに保存するためのコードを作成し、他の人が使用できるようになるまでそれを作り直して、データベースと呼ぶことにしました。
ライブラリは魔法のようには表示されません。それらはプログラマーによって作成され、彼らの生活を楽にし、彼らがより速く働くことを可能にします。
コードをルーチンに入れ、そのコードを実行したいときはいつでもルーチンを呼び出します。
まず、再利用可能な関数を備えたライブラリを作成します。それらは、さまざまなアプリケーションとリンクできます。それは多くの時間を節約し、再利用を促進します。
また、ライブラリが単体テストされ、文書化されていることを確認してください。したがって、適切なクラス/関数/変数/定数を見つけるのは非常に簡単です。
コードを再利用するには、マスターになる必要があります...
- 物事の本質を捉えた名前を付ける。これは本当に本当に重要です
- 1 つのことだけを行うようにします。これは本当に最初のポイントに戻ります。本質的に名前を付けることができない場合、多くの場合、やりすぎです。
- 物事を論理的な場所に配置します。繰り返しますが、これは物事にうまく名前を付け、その本質を捉えることに戻ります...
- 中心的な概念に基づいて構築されたものでグループ化します。上記と同じですが、言い方が異なります:-)
経験則としては、同じ部分を 3 回使用する場合であり、プロシージャ/関数/ライブラリにするよりも一般化することが明らかに可能です。
しかし、年齢を重ね、プロの開発者としての経験も積むにつれて、コードの再利用が常に最善のアイデアとは限らないと考えるようになりました。これには次の 2 つの理由があります。
将来のニーズを予測するのは難しいため、API を定義して、次に実際に使用するようにするのは非常に困難です。それには 2 倍の時間がかかる可能性があります。1 回一般化すると、2 回目はとにかく書き直すことになります。特に最近のJavaプロジェクトはこれに陥りやすいように思えます。それらは常にフレームワークで常に書き直されているようで、将来的には「統合しやすく」するためです。
大規模な組織 (私はそのメンバーです) では、外部チーム (社内またはサードパーティ) に頼らなければならない場合、問題が発生する可能性があります。あなたの将来は彼らの資金とリソースにかかっています。そのため、外国のコードやライブラリを使用することは大きな負担になる可能性があります。同様に、コードの一部を他のチームと共有すると、チームはあなたがそれを維持することを期待できます。
ただし、これらはビジネス上の理由に似ていることに注意してください。したがって、オープンソースでは、再利用可能であることはほぼ常に良いことです。
問題に答える最善の方法は、重要な関数用に個別のアセンブリを作成することだと思います。このようにして、拡張メソッドを作成したり、ヘルパーアセンブリ自体を変更したりできます。この関数について考えてみてください。
ExportToExcel(リスト日付、文字列ファイル名)
このメソッドは、将来のExcelエクスポート機能に使用できるので、独自のヘルパーアセンブリに保存しないでください。このようにして、これらのアセンブリへの参照を追加するだけです。
最初に注意すべきことは、最も効率的な方法ではありませんが、コピー アンド ペーストを使用することでコードを再利用していることです。以前に解決策を思いついた状況を認識しました。
コードの再利用を検討する際には、主に 2 つの範囲に注意する必要があります。1 つ目はプロジェクト内でのコードの再利用、2 つ目はプロジェクト間でのコードの再利用です。
プロジェクト内でコピーして貼り付けることができるコードがあるという事実は、見ているコードが他の場所で役立つことを示しているはずです。それが関数にして、プロジェクト内で利用できるようにするときです。理想的には、そのコードのすべての出現箇所を新しい関数に置き換える必要があります。これにより、(a) 冗長なコードが削減され、(b) そのコードのチャンク内のバグを多数ではなく 1 つの関数で修正するだけで済むようになります。
2 番目の範囲であるプロジェクト間でのコードの再利用では、最大限の利益を得るために、さらに組織化が必要です。この問題は、他のいくつかの SO の質問で対処されています。こことここ。
プロジェクト全体で再利用される可能性が高いコードを、できるだけ自己完結型のソース ファイルに編成することから始めるとよいでしょう。必要なプロジェクト固有のサポート コードの量を最小限に抑えると、新しいプロジェクトでファイル全体を簡単に再利用できるようになります。これは、プロジェクト固有のデータ型の使用を最小限に抑えること、プロジェクト固有のグローバル変数の使用を最小限に抑えることなどを意味します。
これは、環境で役立つことがわかっている関数を含むユーティリティ ファイルを作成することを意味する場合があります。例えば。データベースに依存するプロジェクトを頻繁に開発する場合は、共通のデータベース機能。
簡単:コードをコピーして貼り付けることに気付いたときはいつでも、すぐに新しい関数にコードを取り出してください(つまり、コードを数回CPした後で実行しないでください)。
プロジェクトのサイズに応じて、答えが変わる可能性があります。
小規模なプロジェクトの場合は、すべてのDBアクセスを行うDatabaseHelperクラスを設定することをお勧めします。これは、接続の開閉とDBコードの実行のラッパーにすぎません。次に、より高いレベルで、実行されるDBCommandを記述するだけです。
同様の手法を大規模なプロジェクトに使用することもできますが、追加の作業、インターフェイスの追加、DI、およびデータベースについて知っておくべきことの抽象化が必要になります。
ORM、DAAB、またはパターンと実践グループを調べてみることもできます
オレのC&Pを防ぐ方法については?-コードを作成するときは、定期的にコードを確認する必要があります。類似したコードブロックがあり、パラメーターが1つか2つしか変化しない場合は、常に独自のメソッドにリファクタリングするのに適しています。
今私の擬似コードの例のために:
Function GetCustomer(ID) as Customer
Dim CMD as New DBCmd("SQL or Stored Proc")
CMD.Paramaters.Add("CustID",DBType,Length).Value = ID
Dim DHelper as New DatabaseHelper
DR = DHelper.GetReader(CMD)
Dim RtnCust as New Customer(Dx)
Return RtnCust
End Function
Class DataHelper
Public Function GetDataTable(cmd) as DataTable
Write the DB access code stuff here.
GetConnectionString
OpenConnection
Do DB Operation
Close Connection
End Function
Public Function GetDataReader(cmd) as DataReader
Public Function GetDataSet(cmd) as DataSet
... And So on ...
End Class
あなたが与える例の場合、適切な解決策は、ブロックを貼り付けるたびに編集するものが何であれ、パラメーターとして受け取る関数を作成し、適切なデータをパラメーターとしてその関数を呼び出すことです。
使用しているプログラミング言語によって多少異なります。ほとんどの言語であなたはできます
- 関数を記述し、バリエーションを許可するようにパラメーター化します
- さまざまなデータを保持するメンバーを含む関数オブジェクトを記述します
- さらに複雑なバリエーションを実装する(関数オブジェクト?)クラスの階層を開発する
- C ++では、コンパイル時にさまざまな関数またはクラスを生成するためのテンプレートを開発することもできます。
他の人の関数やライブラリを使用する習慣を身に付けてみてください。
通常、特定の問題には十分にテストされたエレガントな解決策があることがわかります。
見つけた解決策が完全に適合していなくても、他の人がどのように問題に取り組んでいるかを確認することで、問題について多くの洞察を得ることができます。
これは2つのレベルで行います。まず、クラスまたは名前空間内で、そのスコープで再利用されるコードピースを別のメソッドに配置し、呼び出されていることを確認します。
2番目はあなたが説明している場合に似たものです。これは、より広く再利用できるライブラリまたはヘルパー/ユーティリティクラスに配置するのに適した候補です。
他の人が再利用できるかどうかという観点から、行っているすべてのことを評価することが重要です。これは、私たちのほとんどが気付いていないプログラミングへの基本的なアプローチでなければなりません。
再利用するものはすべて、より詳細に文書化する必要があることに注意してください。その命名規則は明確であり、すべてのパラメーター、戻り結果、および必要な制約/制限/前提条件は、(コードまたはヘルプファイルで)明確に文書化する必要があります。