C#上級

上級 C#で学ぶリファクタリング|練習問題編

導入

リファクタリングは、既存のコードを改善し、可読性や保守性を向上させるための重要なプロセスです。特に大規模なプロジェクトでは、コードの複雑さが増し、手を加えるべき部分が増えていきます。本記事では、C#を用いて具体的なリファクタリングのシチュエーションを考察し、実務で役立つ視点を提供します。

教科書レベルの解説(リファクタリング)

重要な概念の整理

リファクタリングには、コードの動作を変えずに構造を改善することが求められます。特に、以下のポイントに注意が必要です。

  • コードの可読性: 他の開発者が理解しやすいコードを書くこと。
  • 重複の排除: 同じコードが複数箇所に存在することを避ける。
  • 単一責任の原則: 各クラスやメソッドが一つの責任を持つように設計する。

コード例(C#)


public class Order
{
    public decimal CalculateTotal(IEnumerable items)
    {
        decimal total = 0;
        foreach (var item in items)
        {
            total += item.Price * item.Quantity;
        }
        return total;
    }
}

コードの行ごとの解説

  1. クラス`Order`は、注文に関連する機能を持つ。
  2. メソッド`CalculateTotal`は、アイテムのリストを受け取り、合計金額を計算する。
  3. ループ内で、各アイテムの価格と数量を掛け算し、合計に加算している。

練習問題編

以下にリファクタリングに関連する練習問題を用意しました。各問題に対する模範解答と解説も併せて記載します。

  1. 問題1: `CalculateTotal`メソッド内のループをリファクタリングして、LINQを使用したバージョンに変更してください。
  2. 模範解答:
  3. 
    public decimal CalculateTotal(IEnumerable items)
    {
        return items.Sum(item => item.Price * item.Quantity);
    }
    
  4. 解説: LINQを用いることで、コードが簡潔になり、可読性が向上する。
  5. 問題2: アイテムの価格や数量が負の値の場合にエラーを投げるように`CalculateTotal`を修正してください。
  6. 模範解答:
  7. 
    public decimal CalculateTotal(IEnumerable items)
    {
        foreach (var item in items)
        {
            if (item.Price < 0 || item.Quantity < 0)
            {
                throw new ArgumentException("Price and quantity must be non-negative.");
            }
        }
        return items.Sum(item => item.Price * item.Quantity);
    }
    
  8. 解説: 入力のバリデーションを追加することで、メソッドの堅牢性を高めている。
  9. 問題3: `Order`クラスに、アイテムの追加や削除の機能を持たせるメソッドを追加し、リファクタリングしてください。
  10. 模範解答:
  11. 
    public void AddItem(Item item)
    {
        items.Add(item);
    }
    
    public void RemoveItem(Item item)
    {
        items.Remove(item);
    }
    
  12. 解説: クラスの責任を明確にし、アイテム管理の機能を追加することで、より使いやすくなっている。

まとめ

  • リファクタリングは、コードの可読性や保守性を向上させるために必要不可欠なプロセスである。
  • 具体的なシチュエーションに基づくリファクタリングを行うことで、実務における実践力を高めることができる。