C#のデザインパターンでリファクタリング!初心者向けコード改善ガイド
生徒
「C#でプログラムを書き終えたあとに、もっときれいに直すことをリファクタリングというんですよね。デザインパターンを使うと何が変わるんですか?」
先生
「その通りです!デザインパターンは、プログラムの設計における先輩たちの知恵です。これを使うと、コードが整理されて、あとから機能を追加しやすくなりますよ。」
生徒
「なるほど!具体的にどのように改善するのか教えてください!」
先生
「では、最初は少し乱雑なコードから、デザインパターンを使って読みやすくする過程を一緒に見ていきましょう。」
1. リファクタリングとデザインパターンとは
まず、言葉の意味を整理しましょう。リファクタリングとは、プログラムの動作を変えずに、中身のコードを整理してきれいにすることです。例えるなら、散らかった部屋の荷物を、使いやすいように整理整頓するようなものです。
そしてデザインパターンとは、プログラム開発でよくある悩みに対する、先人たちが生み出した解決策の型のことです。初心者がゼロから設計するのは大変ですが、デザインパターンという「ひな形」を知っていれば、安全で効率的にプログラムを組むことができます。C#のオブジェクト指向という考え方を活用して、コードを部品化し、メンテナンスしやすい状態を目指します。
2. 初心者が陥りがちなif文だらけのコード
プログラミングを始めたばかりの頃は、条件によって処理を変えるためにif文を多用しがちです。しかし、条件が増えるたびにif文を書き足していくと、コードが長くなりすぎて、どこで何をしているのか分からなくなってしまいます。これをスパゲッティコードと呼びます。麺が絡み合って解けない様子に例えられていますね。
例えば、商品の割引処理を考えるとき、会員ランクによって計算式を変えるプログラムを作ってみましょう。
public class DiscountManager
{
public double CalculatePrice(string memberType, double price)
{
if (memberType == "Gold")
{
return price * 0.8;
}
else if (memberType == "Silver")
{
return price * 0.9;
}
else
{
return price;
}
}
}
このコードは一見簡単ですが、ランクが増えるたびにif文が増えていき、どんどん管理が大変になります。これがリファクタリングが必要な状態です。
3. デザインパターンのストラテジーパターンを学ぶ
このif文の山を整理するために、「ストラテジーパターン」という設計手法を使います。ストラテジー(Strategy)とは日本語で「戦略」という意味です。計算方法という「戦略」をそれぞれ別のクラスに分けてしまうことで、if文を使わずに処理を切り替えられるようになります。
クラスとは、関連するデータと機能を一つにまとめた「設計図」のようなものです。これによって、メインのプログラムは計算の細かい中身を知らなくても、「計算して!」とお願いするだけで良くなります。
4. ストラテジーパターンによるリファクタリングの実践
それでは、先ほどの割引処理をストラテジーパターンで書き換えてみましょう。まずは共通のルールを決めるインターフェースを作成します。インターフェースとは、クラスが必ず持っておくべき機能の約束事です。
public interface IDiscountStrategy
{
double ApplyDiscount(double price);
}
public class GoldDiscount : IDiscountStrategy
{
public double ApplyDiscount(double price) => price * 0.8;
}
public class SilverDiscount : IDiscountStrategy
{
public double ApplyDiscount(double price) => price * 0.9;
}
このように、割引の種類ごとにクラスを作ることで、コードが非常に見通しよくなります。これなら、後から「ブロンズ会員」や「プラチナ会員」を追加したくなっても、新しいクラスを作るだけで済み、元のコードを壊す心配がありません。
5. リファクタリング後のスッキリした呼び出し方
デザインパターンを適用したことで、呼び出し側も非常にシンプルになります。条件分岐のif文が不要になり、プログラムの拡張性が格段に上がります。
public class Cart
{
public double GetFinalPrice(double price, IDiscountStrategy strategy)
{
return strategy.ApplyDiscount(price);
}
}
このようにプログラムを設計しておけば、呼び出すときに「GoldDiscount」を渡せばゴールドの割引になり、「SilverDiscount」を渡せばシルバーの割引になります。プログラムを実行する側で、使う道具を後から自由に入れ替えられるのが、このパターンの素晴らしいところです。
6. コード品質向上のための考え方
リファクタリングを成功させるコツは、一度に大きく変えようとしないことです。最初は複雑なコードでも、少しずつ部品化を進めていくのがポイントです。また、カプセル化という概念も大切です。カプセル化とは、重要なデータを外部から直接いじれないように隠し、決められた方法でしか操作できないようにすることです。これにより、意図しない場所でプログラムが書き換わるミスを防げます。
デザインパターンは「使えば正解」という魔法ではありません。適材適所で使うことが重要です。今回のような条件分岐が多い場合はストラテジーパターンが非常に有効です。コードを読みやすく、誰が見ても理解できる設計にすることは、プログラマーにとって非常に重要なスキルです。
7. プログラムの構成を意識した開発の重要性
最後に、なぜこのような工夫が必要なのかを改めて考えましょう。ソフトウェアは作って終わりではなく、公開したあとに「この機能を追加してほしい」という修正依頼がたくさん来ます。そのときに、コードが複雑だと修正するたびに別の場所でバグが発生してしまいます。バグとは、プログラムの誤作動のことです。デザインパターンを使って整理されたコードは、修正の影響範囲が明確なので、安全に機能追加ができるようになります。
C#は、こうした大規模な開発にも耐えられるように作られた言語です。初心者の方も、まずは小さなプログラムからでも、クラス分けやパターンの適用を意識してみてください。最初は難しく感じるかもしれませんが、意識して書き続けることで、自然ときれいなコードが書けるようになりますよ。