回答:
コードをコメント化。そのブロック、おそらく数百行。理論的には、コメント化されていますが、害はありません。将来必要になるかもしれません。
「コピーパスタ」でもう一つの当たり前のものを叩きます。必要なものとほぼ同じコードをコピーしてから、いくつかの点を変更します(メソッドに抽出するのではなく)。
これは特に、90年代後半の一部の機能テストコードとAPIテストコードでよく見られます。文字通り数百(または数千)のほぼ同一のテストケースであり、3つまたは4つのパラメーターを取るいくつかの関数に分解できた可能性があります。 、データ駆動型の何か。私が大学を卒業した最初の仕事は、文字通り8か月間、廃止された方法を使用していた何千行ものコピーパスタを書き直し、リファクタリングすることでした。テストが完了するまでに、テストファイルは元のサイズの10分の1未満であり、はるかに保守しやすい(そして読みやすい!)ものでした。
私はパターンマニアともっと少ない労力で解決できる解決策についてたくさん書くことができると思いますが、私は最近読んだ素晴らしい記事を指摘したいと思います。単純な解決策が複雑すぎる可能性があるという素晴らしい例を挙げたいと思います。 。
地域
C#では、IDEで折りたたむことができるコードの領域を定義して、そのコードを処理する必要がない限り非表示にすることができます。私は(現在は)数百行にまたがるプロジェクト(私は誇張していると思います)に参加しており、千行関数に複数の領域がありました(ここでも冗談ですが)。
利点として、リージョンを作成した開発者は、リージョン内の特定の機能を識別するのに非常に良い仕事をしました。地域で抽出メソッドを実行して次に進むことができたほどです。
リージョンは、開発者ががらくたを一目で「隠す」ことを奨励します。
DoNotUseRegions
ます。
#region SQL Update
はそれを折りたたみ可能にするので、必要なスクロールは少なくなります。
ループスイッチシーケンス
http://en.wikipedia.org/wiki/Loop-switch_sequence
彼らは私を終わりまで悩ませ、開発者がいかに経験の浅い経験であったかを本当に示しています
大規模なチェックイン
開発者が1週間以上チェックインを行っていないのを見ると嫌いです。それは、彼が行き詰まって助けを求めていないか、または一連の機能を1つの大きなチェックインにまとめていることを意味します。(私は最悪のケースのシナリオを省略しました、彼は何もしていないだけです。それは簡単に解決されます... 2つの単語はあなたが雇われているように聞こえます。)
大きなチェックインを行っている場合、変更セットを特定の機能にリンクできるなど、SCMの多くの利点が失われます。また、多くのマージが必要になる可能性があり、それを正しく行うのは必ずしも容易ではありません。
現在、私はレガシーコードの一部を扱っており、以前のコーダーがリストの最初の要素を取得する方法が気に入っています。
String result;
for(int i = 0; i < someList.size(); i++) {
result = someList.get(i);
break;
}
しかし、このコードで私が見た中で最悪なのは、クラスをインラインJSPページを定義し、スクリプトレットとout.printlnを使用してすべてのHTML、CSS、JavaScriptを記述することです:-(
文字列リテラルのロック
synchronized("one") { /* block one A*/ }
synchronized("one") { /* block one B*/ }
非常に長いクラス名。(JRE内)
com.sun.java.swing.plaf.nimbus.
InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState
貧弱な継承構造
com.sun.corba.se.internal.Interceptors.PIORB extends
com.sun.corba.se.internal.POA.POAORB extends
com.sun.corba.se.internal.iiop.ORB extends
com.sun.corba.se.impl.orb.ORBImpl extends
com.sun.corba.se.spi.orb.ORB extends
com.sun.corba.se.org.omg.CORBA.ORB extends
org.omg.CORBA_2_3.ORB extends
org.omg.CORBA.ORB
ない例外。
public interface FlavorException { }
無意味で不可解なエラー処理
if (properties.size() > 10000)
System.exit(0);
オブジェクトの不要な作成
Class clazz = new Integer(0).getClass();
int num = new Integer(text).intValue();
他の目的で例外をスローする
try {
Integer i = null;
Integer j = i.intValue();
} catch (NullPointerException e) {
System.out.println("Entering "+e.getStackTrace()[0]);
}
静的メソッドのインスタンスオブジェクトの使用。
Thread.currentThread().sleep(100);
非最終フィールドでの同期
synchronized(list) {
list = new ArrayList();
}
定数文字列の無意味なコピー
String s = new String("Hello world");
String.toString()への無意味な呼び出し
String s = "Hello";
String t = s.toString() + " World";
System.gc()を呼び出してメモリを解放する
ローカル変数をnullに設定してメモリを解放する
// list is out of scope anyway.
list = null;
}
パフォーマンス上の理由(またはその他のマイクロマイクロ最適化)のためにi ++の代わりに++ iを使用する
ダミーのイテレータ:
Iterator iCollection = collection.iterator();
for(int i = 0 ; i < collection.size() ; i++ ){
if(collection.get(i) == something){
iCollection.remove();
}
}
シングルトノファクトリー:
public class SomeObject{
private SomeObject() {}
public static SomeObject getInstance(){
return new SomeObject();
}
}
if-else駆動の開発(オープンクローズの原則とも呼ばれます-理解のために変更のためにオープン):
if (sth1){
...
}else if(sth2){
..
}
...
..
else if(sth1000000000000){
...
}
StringPattern(StringObjectとも呼ばれます):
a) sendercode
if(sth1)
str+="#a";
if(sth2)
str+="#b";
...
if(sth1000)
str+="#n";
b) receiver
regexp testing if str contains #a, #b, ... #n
else if
は多くの場合、物事を成し遂げる唯一の方法です。文字列について考えています。スイッチは使用できません。それが有用であるためには、条件は同じである必要があります。
getInstance
が同じインスタンスを返すことを前提としていることです。そのような仮定はカプセル化を壊し、実際には最も一般的なアンチパターンの1つです。
抽象化の逆転、または高レベルのプリミティブの上に低レベルのプリミティブを再発明することは絶対に嫌いです。しかし、時々、これは悪いプログラマーではなく、悪い言語デザイナーによって引き起こされます。例:
関数ポインターの代わりに、メンバー変数のない単一のメソッドクラスと対応するインターフェイス(関数ポインターのテーブルに関して実装)を使用します。Javaのような言語では、選択の余地がないことに注意してください。
MATLABおよびRでは、すべてがプリミティブではなくベクトル/マトリックスであるという主張。
MATLABをbashしている間、整数がないというのはどうでしょうか。したがって、整数が必要な場合はdoubleを使用する必要があります。
ループを記述するために関数呼び出しを使用する必要がある純粋な関数型言語。
多目的Java Bean-
いくつかの異なる種類の操作で使用される、多くの変数を持つJava Bean。各操作は、Bean変数の任意のサブセットを使用し、その他は無視します。GUI状態のいくつかの変数、コンポーネント間で受け渡すためにスローされるいくつかの変数、おそらくもう使用されていないいくつかの変数。最良の例には、パターンの評価を妨げるドキュメントがありません。
また、最愛の人を忘れることはできません
try{
... //many lines of likely dangerous operations
}
catch(Exception e){}
私に多くの悲しみを引き起こしたのは、「空の大きな地図」パターンです。適切なオブジェクトを使用する代わりにマップを投げる。デバッグを行わないと、どのような「変数」が含まれているかがわかりません。また、コードを逆にトレースしないと、何が含まれているかもわかりません。通常、文字列をオブジェクトに、または文字列を文字列にマッピングします。これらは、プリミティブに解析される可能性があります。
私が見た中で最悪のアンチパターンの1つは、コンピューターのメモリを使用する代わりに、データベーステーブルを一時ストレージとして使用することです。
問題ドメインは独自のものであり、説明することはできませんが、基本的な問題を理解する必要はありません。これは、バックエンドデータベースを備えたJavaで記述されたGUIアプリケーションでした。特定の入力データを取得して操作し、処理されたデータをデータベースにコミットすることでした。
私たちのプロジェクトには、後で処理するために中間値を保存するかなり複雑なアルゴリズムがあります。一時オブジェクトを...オブジェクトにカプセル化する代わりに、データベーステーブルを「t_object」のように作成しました。値が計算されるたびに、このテーブルに追加されました。アルゴリズムが機能を終えると、すべての中間値が選択され、1つの大きなMapオブジェクトですべて処理されます。すべての処理が完了すると、保存するようにマークされた残りの値が実際のデータベーススキーマに追加され、「t_object」テーブルの一時エントリが破棄されます。
テーブルは一意のリストのようにも使用され、データは一度しか存在できませんでした。テーブルに制約を実装した場合、これは設計の適切な機能だったかもしれませんが、データが存在するかどうかを確認するためにテーブル全体を繰り返し処理することになりました。(いいえ、CONTAINSでwhere句を使用するクエリを使用していませんでした)
この設計が原因で発生した問題のいくつかは、具体的にはデバッグに関するものでした。アプリケーションはデータをパイプライン処理するように構築されているため、このアルゴリズムに到達する前にデータを前処理する複数のGUIがあります。デバッグプロセスは、テストケースを処理し、上記のセクションを完了した直後に一時停止することでした。次に、データベースにクエリを実行して、このテーブルに含まれているデータを確認します。
私たちが発見した別の問題は、データがこの一時テーブルから適切に削除されておらず、将来の実行に干渉することでした。これは、例外が適切に処理されていないため、アプリケーションが適切に終了せず、制御対象のテーブルのデータを削除していないことが原因であることがわかりました。
基本的なオブジェクト指向設計を使用し、すべてをメモリに保持していた場合、上記の問題は発生しませんでした。まず、アプリケーションにブレークポイントを簡単に設定し、スタックとヒープのメモリを検査できるため、デバッグは簡単でした。次に、アプリケーションからの異常終了時に、Javaメモリがデータベースから削除されることを心配することなく、自然にクリーンアップされます。
注:このパターンが本質的に悪いと言っているのではありませんが、この例では、基本的なOOの原則で十分である場合は不要であることがわかりました。
このアンチパターンの名前がわからないのは、このようなことをしたのが初めてだからです。皆さんがこのパターンについて考えることができる良い名前はありますか?
カートビフォアザホース-別名YouMightNeedIt
例えば:
IMOで私が見た中で最悪のアンチパターンは、「臭いパターンが必要ない」アンチパターンです。デザインパターンは時間の無駄であり、一緒にスロープしてコピー/コピーするだけでコードをより速く書くことができるという考え必要に応じて貼り付けます。
名誉ある言及は、以下の古いVB6スタイルを使用してデータベースからオブジェクトをロードするコードを持つことです。
Foobar oFoo = new Foobar();
oFoo.FooID = 42;
if (oFoo.Load()) {
// do something with oFoo
}
それ自体は実際にはアンチパターンではありませんが、適切なアーキテクチャと懸念事項の分離を活用できないことを示しています。
また、次のようなもの:
// this name is misleading, we may not always want to stand in fire,
// we may want to stand in slime or voidzones or ice patches...
public Foobar StandInFire() { }
// why is this here???
public string BeatWithNerfBat(string whom) { }
// ????
public int GivePony(string to) { }