リビルド36計(1-6)


再構築は、実は簡単で、プログラムを理解しやすくし、メンテナンス性があり、構造が合理的になることを目的としています.再構築は、関数により良い名前を付けたり、大きな関数をいくつかの小さな関数に分割したりするなど、私たちが普段コードを書く過程で欠かせない部分です.再構築の古典書にはMartin Flowerの「再構築-既存コードの設計を改善する」、Joshua Kerievskyの「再構築とモード」が含まれています.このシリーズのいわゆる36計は私が長年にわたって最も頻繁に使用してきた再構築戦略と符号化準則であり、自分でまとめたものもあり、本で提案したものもあり、皆さんに役に立つことを望んでいます.
第一計:パラメータリストのオブジェクト化
  公有関数のパラメータはできるだけ変わらないようにしなければならない.多くの場所で呼び出されるため、パラメータを変更した後、呼び出し先を変更する必要がある.また、パラメータリストは長すぎるべきではなく、数をできるだけ5つ以内に保つと、長パラメータリストは関数の呼び出しの難易度を増加させる.パラメータが多いか、パラメータが頻繁に変化する公有関数については、パラメータオブジェクトを導入することが好ましい.すなわち、関数のパラメータは1つしかない.これはパラメータオブジェクトであり、具体的なパラメータはオブジェクトに宣言され、関数にパラメータオブジェクトを導入するには以下のいくつかのメリットがある.
1、関数インタフェースの不変性を維持し、関数パラメータを修正するには、パラメータオブジェクトのメンバー変数を修正するだけです.
2、呼び出しが便利で、呼び出し側はパラメータの順序に関心を持たなくてもいい.
次のコードクリップは、ユーザー関数を追加する宣言です.
public long insertUser(String name,int age,String email,String address,String phone,String birthDay)

[size=medium]ユーザーのフィールドを追加または削除するたびにinsertUserのパラメータリストを変更し、呼び出し元も変更する必要があり、パラメータが多い場合は記憶しにくい.
次に、パラメータオブジェクトを導入した形式を示します.
public class UserParam{
  public String name;
  public int age;
  public String email;
  public String address;
  public String phone;
  public String birthDay;
}

public long insertUser(UserParam user);

第2計:if elseの代わりに条件演算子の付与
  条件に基づいて変数に値を割り当てる場合は、if-elseを使用する2つの方法があります.
int value;
if(condition)
  value = 1;
else
  value = 2;

もう1つは、条件演算子を使用します.
int value = condition ? 1 : 2;

2つ目の方法は明らかに1つ目の方法より良いですが、多くの人が1つ目の方法が好きで、if-elseが慣れているかもしれません.
第三計:システム資源の節約
コードを書くときでも、システムが提供するリソースを勝手に浪費しないで、スペースを消費し、パフォーマンスに影響を与えるオブジェクトについては、本当に使用するまで作成または初期化する必要があります.そのため、これらのオブジェクトを提供する関数の実装では、できるだけ次の形式を採用します.
//          
public class DataBaseConnectionHolder{
  private Connection conn;

  public Connection getConnection(){
     if(conn == null){
       conn = new Connection();
       conn.init(); 
      }
     return conn;
   }
}

さらに、オブジェクトプールなどのキャッシュメカニズムを導入することで、システムリソースを十分に活用できます.
第四計:インタフェースに抽象バージョンを導入する
  新しいインタフェースを宣言するときは、インタフェースが変更されないことを保証することはできません.よく変更される可能性があります.インタフェースを変更するたびに、対応する実装クラスを変更する必要があります.インタフェースがパブリックライブラリの一部である場合、インタフェースを変更する代価は大きく、インタフェースを変更するすべてのプログラムは再修正、コンパイルする必要があります.この問題は、インタフェースに抽象バージョンを導入することで解決できます.たとえば、次のインタフェースに抽象クラスを追加します.
public interface Widget{
  public void draw();
  public void layout();
  public void invalidate();
  public void show();
}
 
public abstract class AbstractWidget implements Widget{
  public abstract void draw();
  public void layout(){};
  public void invalidate(){};
  public void show(){};
}

これにより、Widgetの実装クラスはAbstractWidgetから直接継承され、Widgetインタフェースを変更する場合は、AbstractWidgetを変更するだけで、他の実装クラスには影響しません.
第五計:消滅魔法数
  プログラミング初心者は一般的にタイプや状態を表す数字を直接処理論理に書き、コードの著者はその数字が表す意味を理解できるが、他の人はこのコードを読むと分からない可能性が高い.コードの作者がこのコードをもう少し見ても、その数字の意味を忘れてしまう可能性があります.また、魔法数の値を修正しようとすると、過程が煩雑で、漏れてしまう可能性が高いので、プログラム中のすべての魔法数を徹底的に消滅させ、定数定義、列挙などで魔法数の出現を避けるのが最善の方法です.
第六計:断言・異常を用いて実現の正確性を確保する
  断言を使用する目的は、debugバージョンのプログラムの正確性を確保する手段であり、正式にリリースされたバージョンでは断言は役に立たないことを他のプログラマーコードのどこかで守らなければならないルールを伝えることです.Javaでは、断言を有効にするにはコンパイルオプションを追加する必要がありますが、例外を投げ出すことで同じ目的を達成することができます.例外を使用するのは断言よりも危険です.プログラムの正式なリリースではクラッシュを引き起こす可能性がありますが、クラッシュはプログラムの奇妙な行為よりも良い場合があります.たとえば、次のようにします.
//       
public class Collection{
  //         
  public void addElement(Element e){};
 
  //          
  public void getElement(int index){}; 
}

//         
public class ReadOnlyCollection extends Collection{
  //         
  public void addElement(Element e){
    throw new UnsupportedOperationException("    ,       ");
  }
  
  //          
  public void getElement(int index){};
}

ReadOnlyColletion派生クラスを呼び出すにはルールを守らなければなりません.addElementを呼び出すことはできません.そうしないと、異常を投げ出してプログラムを乾かします.
ref:http://blog.csdn.net/m13666368773/article/details/7472201