テクニック:メソッドのコンパイル(M. Fowlerによるリファクタリング)

ダックでコードを開始します(M. Fowlerによるリファクタリング)

本「 リファクタリング 」のリファクタリング手法の続き 既存のコードの改善Martin Fowler



構文はC#で記述されますが、主なことはアイデアを理解することであり、他のプログラミング言語でも使用できます。



メソッドのコンパイル。



  1. メソッドを強調表示するコードの一部を名前が意味を説明するメソッドに変換する )。

    longメソッドを論理サブメソッドに分割します。

    から

    void PrintUserInfo(decimal amount) { PrintParentInfo(); Console.WriteLine(string.Format(": {0}", name); Console.WriteLine(string.Format(": {0}", age); Console.WriteLine(string.Format("-: {0}", amount); }
          
          







     void PrintUserInfo(decimal amount) { PrintParentInfo(); PrintUserDetails(decimal amount); } void PrintUserDetails(decimal amount) { Console.WriteLine(string.Format(": {0}", name); Console.WriteLine(string.Format(": {0}", age); Console.WriteLine(string.Format("-: {0}", amount); }
          
          





  2. メソッドの埋め込みメソッドを呼び出すコードにメソッドの本体を入れて、メソッドを削除します )。

    過度の間接化(メソッドへの分解)は、クラスを複雑にする可能性があります。

    から

     int GetPoints() { return HasMaxSum() ? decimal.One : decimal.Zero; } bool HasMaxSum() { return summ >= maxSumm; }
          
          







     int GetPoints() { return summ >= maxSumm ? decimal.One : decimal.Zero; }
          
          





  3. 一時変数の埋め込みこの変数へのすべての参照をこの式に置き換えます )。

    追加の中間コード。

    から

     decimal cost = order.GetCost(); return cost > 1000;
          
          







     return order.GetCost() > 1000;
          
          





  4. 一時変数をメソッド呼び出しに置き換えます式をメソッドに変換します )。

    このような場所が多数ある場合、メソッドはクラス内のどこからでも呼び出すことができます。

    から

     decimal MethodA() { decimal summ = amount * cost; if(summ > 1000) { //do something return summ * 10; } return 0; } decimal MethodB() { //do something decimal summ = amount * cost; return summ != 0 ? summ * 100 : 1; }
          
          







     decimal MethodA() { decimal summ = GetSumm(); if(summ > 1000) { //do something return summ * 10; } return 0; } decimal MethodB() { //do something return GetSumm() != 0 ? GetSumm() * 100 : 1; } decimal GetSumm() { return amount * cost; }
          
          





  5. 説明変数の導入式の結果またはその一部を一時変数に入れる )。

    コードの読み取りと理解が簡素化されます。

    から

     if(VisualItems.ColumnCount == FocusedCell.X && (key == Keys.Alt | Keys.Shift) && WasInitialized() && (resize > 0)) { // do something }
          
          







     bool isLastFocusedColumn = VisualItems.ColumnCount == FocusedCell.X; bool altShiftPressed = (key == Keys.Alt | Keys.Shift); bool wasResized = resize > 0; if(isLastFocusedColumn && altShiftPressed && WasInitialized() && wasResized) { // do something }
          
          





  6. 説明変数を分割します割り当てごとに個別の一時変数を作成します )。

    コードの読み取りと理解が簡素化されます。

    から

     decimal temp = 2 * (height + width); Console.WriteLine(temp); temp = height * width; Console.WriteLine(temp);
          
          







     decimal perimetr = 2 * (height + width); Console.WriteLine(perimetr); decimal area = height * width; Console.WriteLine(area);
          
          





  7. パラメーターへの割り当てを削除します一時変数を使用することをお勧めします )。

    メソッドは、明示的に指定されていない限り、入力パラメーターの値を変更しないでください(out、ref in C#など)。

    から

     int Discount(int amount, bool useDefaultDiscount, DateTime date) { if(amount == 0 && useDefaultDiscount) { amount = 10; } return amount; }
          
          







     int Discount(int amount, bool useDefaultDiscount, DateTime date) { int result = amount; if(amount == 0 && useDefaultDiscount) { result = 10; } return result; }
          
          





  8. メソッドをメソッドオブジェクトに置き換えるメソッドを別のオブジェクトに変換する )。

    コードの柔軟性のためのクラス分解。

    から

     class MessageSender { public Send(string title, string body) { // do something // long calculation of some condition if(condition) { // sending message } } }
          
          







     class MessageSender { public Send(string title, string body, decimal percent, int quantity) { // do something Condition condition = new Condition (percent, quantity, dateTime); if(condition.Calculate()) { // sending message } } } class Condition { public Condition(decimal percent, int quantity, DateTime dt) { } public bool Calculate() { // long calculation of some condition } }
          
          





  9. アルゴリズムの置換アルゴリズムをより理解しやすいものに置き換えます )。

    読みやすさやパフォーマンスを向上させるためのコードの最適化。

    から

     string FoundPerson(List<string> people) { foreach(var person in people) { if(person == "Max") { return "Max"; } else if(person == "Bill") { return "Bill"; } else if(person == "John") { return "John"; } return ""; } }
          
          







     string FoundPerson(List<string> people) { var candidates = new List<string>{ "Max", "Bill", "John"}; foreach(var person in people) { if(candidates.Contains(person)) { return person; } } return ""; }
          
          







少し現実とコードレビュー手順。



リファクタリングする前に、または行われた変更を確認するために、コードレビュー手順が使用されます。

この場合、レビュアーの「コメント」(基準)に焦点を当てます。



現実には、これらの基準間の線はプログラマーごとに異なる場合がありますが、これは許容範囲です-通常です。 レビュアーに3番目の基準がない場合、つまり、 彼は常に正しい、そしてもし彼が正しくないなら、それを彼に証明する(しかし、すべてが決定的ではなく、まだ数学ではない)。 反対に、すでにコードコミッターになっているため、3番目の基準のみが適用されます。

そして、そのような2人が衝突するとき、それは炎であり、悲鳴を上げます(私は母親と一緒に見ました:))。

衝突を解決するには、3つの力が必要です。原則として、別のプログラマー(できれば経験が豊富)が意見を述べる必要があります。



利益相反とその解決策については、次の記事で説明します。



All Articles