プログラミングで、過度に使用されている(IEが本来あるべきものよりも過度に使用されている)、または悪用されている、またはすべてに少し使用されているが、人々が試みる多くの問題に対する本当に良い解決策ではないテクニックがありますか?それで解決します。
正規表現、ある種のデザインパターン、アルゴリズムなど、まったく異なるものを使用できます。たぶん、人々は多重継承などを乱用すると思います。
プログラミングで、過度に使用されている(IEが本来あるべきものよりも過度に使用されている)、または悪用されている、またはすべてに少し使用されているが、人々が試みる多くの問題に対する本当に良い解決策ではないテクニックがありますか?それで解決します。
正規表現、ある種のデザインパターン、アルゴリズムなど、まったく異なるものを使用できます。たぶん、人々は多重継承などを乱用すると思います。
回答:
コード内のコメント
大学教授が、次のコードはforループであり、1からxの数まで反復するという10行のコメントを書くことを生徒に教える必要がないことを理解してほしい。私はコードでそれを見ることができます!
最初に自己文書化コードを記述し、次に適切に自己文書化できないものについて適切にコメントするように指導します。ソフトウェアの世界がより良い場所になるでしょう。
Clean Code
、ファウラーは、古いドキュメントはドキュメントがないよりも悪いこと、そしてすべてのコメントが古くなり、ドキュメントのコードから移行する傾向があることを明確に述べています。その本全体は、自己文書化コードの書き方に関するものです。
シングルトンデザインパターン。
確かに、これは有用なパターンですが、新しいプログラマーはこのパターンについて学ぶたびに、作成するすべてのクラスにそれを適用しようとし始めます。
$this->
。PHPは腐った言語なので、フレームワークが優れているとは期待できません。
ダムプログラミングを保護するための最も邪悪なもの。すべてをtryキャッチに入れ、キャッチで何もしない
try
{
int total = 1;
int avg = 0;
var answer = total/avg;
}
catch (Exception)
{
}
何もせず、愚かなロジックを処理するように設計されたtry catchを見ると、身震いします。一般に、try catchは使いすぎですが、場合によっては非常に便利です。
StackOverflowを使用して問題を解決するのではなく、問題を解決します。
SOに関する豊富な知識を見つけた新しいプログラマーは(あまりにも頻繁に)考えて物を試す前に投稿します。
私の時代、私たちは本からコーディングしなければなりませんでした。インターネットもSOもありませんでした。今私の芝生を下車します。
明らかにOOP。それは非常に価値がありますが、誤って使用すると、明確なコードがかなり簡単にわかりにくくなり(RでのS4プログラミングの例が思い浮かぶ)、不必要な大きなオーバーヘッドが発生し、パフォーマンスに多大な時間がかかります。
別のことは(たとえばPerlで)OOPはしばしば同じことを逆に書くことになります:これのresult = $object ->function(pars)
代わりにresult = function(object, pars)
時々理にかなっていますが、手続き型プログラミングと混ぜるとコードを読むのはかなり混乱する可能性があります。それとは別に、設計を改善しない場合はオーバーヘッドを増やすだけです。それは、シングルトンパターンについても言われていることに帰着します。すべてではなく、使用する必要があります。
私は自分でOOPを使用していますが、私の分野(科学計算)でのパフォーマンスは大きな問題であり、すべての学生がJavaを取得するようになった現在、OOPはしばしば乱用されています。大きな問題の処理、概念化などに最適です。ただし、たとえばBioPerlでDNAシーケンスを使用する場合、毎回オブジェクトを使用し、ゲッターとセッターを一貫して使用すると、計算時間が10倍になります。コードが数時間ではなく数日間実行されている場合、その違いは本当に重要です。
Foo.DoX().DoY().DoZ()
)は便利ですが、何かを行う唯一の方法ではありません。以下のような関数組成物は、(doZ . doY . doX $ foo
完全に有効な代替手段です。
ASP.NET Webformsで数年を過ごした後、私は明確に言わなければなりません。
Webフォームでレイヤー化されたテスト可能なアプリケーションを作成することは完全に可能ですが、Visual Studioでは、開発者がすべてのUIコードに散らばったアプリケーションロジックを使用して、データソースに緊密にバインドされたフォームにワンクリックで簡単に移動できます。
スティーブ・サンダーソンは、このアンチパターンについて、Pro ASP.NET MVCの本で説明したよりもはるかに優れていると説明しています。
スマートUIアプリケーションを構築するために、開発者は通常、一連のUIウィジェットをキャンバスにドラッグすることで最初にUIを構築し、次に可能なボタンクリックまたは他のUIイベントごとにイベントハンドラーコードを入力します。すべてのアプリケーションロジックは、これらのイベントハンドラーに存在します。ユーザー入力を受け入れて検証し、データアクセスとストレージを実行し、UIを更新してフィードバックを提供するロジックです。アプリケーション全体は、これらのイベントハンドラで構成されています。基本的に、これはVisual Studioの前に初心者を置くとデフォルトで出てくる傾向があります。この設計では、懸念の分離はまったくありません。すべてが融合され、発生する可能性のあるさまざまなUIイベントに関してのみ配置されます。ロジックまたはビジネスルールを複数のハンドラーに適用する必要がある場合、通常、コードはコピーアンドペーストされ、または、ランダムに選択された特定のセグメントが静的ユーティリティクラスに含まれます。非常に多くの明白な理由から、この種の設計パターンはしばしばアンチパターンと呼ばれます。
これはときどき見られますが、通常はブール式を完全に理解していないことが原因です。
if (someCondition == true)
bool
、is
またはhas
で始まるs など、変数に適切な名前を付けた場合、でコードをより明示的にする必要はありません= true
。
再実装コア(または他の方法で提供される)機能は、いずれか、その存在の無知のため、またはカスタマイズのために知覚される必要性。
継承。
is-aを強制しないでください。
コンパイラーをデバッガーとして使用します。
コンパイラの警告を無視するか、完全にオフにします。
グローバル変数。
すべてのデザインパターン。
彼らは塩や砂糖のようなものです。あなたの食べ物にあるそれらのいくつかはそれを素晴らしいものにし、それらの多くはあなたの食べ物を吸います。
誤解しないでください。デザインパターンは素晴らしいテクニックです。よく使いました。しかし、時には、問題に一致しなくても、これらの「デザインパターンを使用する必要がある」というプログラマー(一部は私の元ボス)を見つけます!!!
1つの例は、「Linear / Sequential Collections」向けの「Visitor Pattern」です。一度、ツリーデータ構造で作業する必要がありました。各アイテムを「訪問」するために、非デザインパターンメソッドをコーディングし、元のボスが「訪問者パターン」の使用または適合を主張しています。次に、セカンドオピニオンのためにネットを閲覧します。まあ、他のプログラマーも同じ状況と同じ解決策を持っています。そして、それを「ツリー/階層訪問者パターン」と呼びます。新しいデザインパターンとして
「Design Patterns」ブックの新しいバージョンで、既存のパターンに新しいパターンとして追加されることを願っています。
フロー制御として例外を使用します。この答えに似ていますが、異なります。
例外を飲み込むことは、コード内のバグを見つけるのが難しい、不可解なことを引き起こすため、悪い形です。一方、フロー制御として例外を使用すると、コードの効率が大幅に低下し、概念的にずさんになるため、悪いです。
例外処理は、数字が予想されるアルファベット文字を入力するようなものではなく、本当に例外的な(duh)予期しないシナリオを処理するためにのみ使用する必要があります。この種の例外の悪用は、Javaの世界の悪いプログラマーの間では非常に一般的です。
内部配列の公開
public class Data {
int[] x;
public void setArray(int[] x) {
this.x = x;
}
public int[] getArray() {
return x;
}
}
http://www.oracle.com/technetwork/java/seccodeguide-139067.htmlによると
状態を共有することが目的でない限り、戻る前に可変オブジェクトをコピーします。
可変状態とループ。あなたはそれらをほとんど必要とせず、ほとんど常にそれらなしでより良いコードを取得します。
たとえば、これはStackOverflowスレッドから直接取得されます。
// ECMAScript
var thing, things_by_type = {};
for (var i = 0; i < things.length; i++) {
thing = things[i];
if(things_by_type[thing.type]) {
things_by_type[thing.type].push(thing);
} else {
things_by_type[thing.type] = [thing];
}
}
# Ruby
things_by_type = {}
things.each do |thing|
(things_by_type[thing.type] ||= []) << thing
end
彼らは両方とも同じことをしています。しかし、私は彼らが何をしているのか分かりません。幸いなことに、質問は実際に彼らが何をしているかを説明しているので、次のように書き直すことができました。
// ECMAScript
things.reduce(function (acc, thing) {
(acc[thing.type] || (acc[thing.type] = [])).push(thing);
return acc;
}, {});
# Ruby
things.group_by(&:type)
// Scala
things groupBy(_.type)
// C#
from thing in things group thing by thing.Type // or
things.GroupBy(thing => thing.Type);
ループも変更可能な状態もありません。さて、わかりました、明示的なループとループカウンターはありません。
コードははるかに短くなり、はるかにシンプルになり、コードが何をすべきかの説明に似たものになり(特にRubyの場合は、「タイプごとにグループ化する」と言われます)、エラーが発生しにくくなりました。ループインデックスと終了条件がないため、ループインデックスと終了条件を使用して、アレイの端を越えて実行される危険、フェンスポストエラー、オフバイワンエラーはありません。
(acc[thing.type] || (acc[thing.type] = []))
への `= [thing] , unless you want to add
thing`を2回読むのではなく、...と思っています。
モッキング。コードに過度にデカップリングするための人工的な要件が多すぎて、ラビオリのコードが過剰に設計されており、手続き型または機能的な設計が問題の単純な解決策である場合に、OOスタイルの設計を喉に押し付けます。
プロパティ。これは議論の余地があることはわかっていますが、.netではプロパティが非常に使いすぎていると感じています。
これらの2行の違いは何ですか?
public string Property { get; set; }
public string Field;
開発者にとっての違いは、まったくありません。あなたはライブラリを書いている、そうならばコンパイルされた形式は、ほんの少しの違いとそのライブラリがプログラムでアップグレードされようとしている、とあなたはそのプラグインのインターフェイスを書いている場合は、たとえば(プログラム自身を再コンパイルすることはできませんソフトウェアの複数のバージョンで機能する必要があります)、パブリックフィールドはプロパティに置き換えることができないため、パブリックフィールドを使用しないでください。それ以外の場合、フィールドを使用するか、修飾子を付けずに自動プロパティを使用するかにまったく違いはありません。
YAGNI
私は、この場合には逸脱感じていないのコストは何もありません)
;
する{ get { ... } set { ... } }
よりも多くの仕事に変更{ get; set; }
するのは{ get { ... } set { ... } }
どうですか?