【C#】シンプル電話帳のリファクタリング(特定事例)

電話帳向けの練習コードのリファクタリング例になります

読めるか確認してみましょう

リファクタリングコード例1

このリファクタリングにより、コードがよりモジュール化され、可読性が向上しました
また、ファイル読み込みのエラー処理も追加されています

using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;

namespace PhoneBook
{
    public partial class Form1 : Form
    {
        private Dictionary<string, string> phoneBook;

        public Form1()
        {
            InitializeComponent();

            InitializePhoneBook();

            DisplayNamesInList();
        }

        private void InitializePhoneBook()
        {
            phoneBook = new Dictionary<string, string>();
            ReadFromFile();
        }

        private void ReadFromFile()
        {
            string filePath = @"..\..\data.txt";

            try
            {
                using (StreamReader file = new StreamReader(filePath))
                {
                    while (!file.EndOfStream)
                    {
                        string line = file.ReadLine();
                        string[] data = line.Split(',');

                        if (data.Length >= 2)
                        {
                            string name = data[0];
                            string phoneNumber = data[1];
                            phoneBook[name] = phoneNumber;
                        }
                    }
                }
            }
            catch (IOException ex)
            {
                MessageBox.Show("ファイル読み込みエラー: " + ex.Message);
            }
        }

        private void DisplayNamesInList()
        {
            foreach (string name in phoneBook.Keys)
            {
                nameList.Items.Add(name);
            }
        }

        private void NameSelected(object sender, EventArgs e)
        {
            string selectedName = nameList.Text;

            if (phoneBook.TryGetValue(selectedName, out string phoneNumber))
            {
                this.phoneNumber.Text = phoneNumber;
            }
            else
            {
                this.phoneNumber.Text = "電話番号が見つかりません";
            }
        }
    }
}

解説

InitializePhoneBook() メソッド

電話帳の初期化を行うためのメソッドです

phoneBook ディクショナリを新しく作成し、ReadFromFile() メソッドを呼び出してファイルからデータを読み込みます

ReadFromFile() メソッド

ファイルから電話帳データを読み込むためのメソッドです

StreamReader を使用してファイルを読み込みながら、各行をカンマで分割して名前と電話番号の組み合わせをディクショナリに追加します

ファイル読み込み中にエラーが発生した場合、例外をキャッチしてエラーメッセージを表示します

DisplayNamesInList() メソッド

電話帳の名前をリストボックスに表示するためのメソッドです
phoneBook ディクショナリのキー(名前)を取得し、それぞれをリストボックスに追加します

NameSelected イベントハンドラ

名前がリストボックスで選択されたときに呼び出されるメソッドです

選択された名前を取得し、phoneBook ディクショナリから対応する電話番号を取得して表示します
ディクショナリ内に名前が存在しない場合はエラーメッセージを表示します

これにより、コードはより構造化され、関数ごとに役割が明確になりました
また、ファイル読み込み時のエラー処理も強化され、エラーメッセージが表示されるようになりました
リファクタリングによって、コードの保守性や拡張性が向上しました

リファクタリングコード例2

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;

namespace PhoneBook
{
    public partial class Form1 : Form
    {
        private readonly Dictionary<string, string> phoneBook = new Dictionary<string, string>();

        public Form1()
        {
            InitializeComponent();
            LoadPhoneBook();
            PopulateNameList();
        }

        private void LoadPhoneBook()
        {
            string filePath = @"..\..\data.txt";

            if (File.Exists(filePath))
            {
                foreach (string line in File.ReadLines(filePath))
                {
                    string[] data = line.Split(',');
                    if (data.Length >= 2)
                    {
                        phoneBook[data[0]] = data[1];
                    }
                }
            }
        }

        private void PopulateNameList()
        {
            nameList.Items.AddRange(phoneBook.Keys.ToArray());
        }

        private void NameSelected(object sender, EventArgs e)
        {
            if (phoneBook.TryGetValue(nameList.Text, out string phoneNumber))
            {
                this.phoneNumber.Text = phoneNumber;
            }
        }
    }
}

電話帳の名前一覧は、PopulateNameListメソッド(名前リストの入力メソッド)でまとめてリストボックスに登録しています
phoneBookインスタンス変数は宣言時にnewキーワードでインスタンス化しています
File.Exists(filePath)メソッドでファイルが存在するか確認し、if文で存在している時だけ処理をするようにしています
また、ファイルの読み込み処理にFile.ReadLinesメソッドを使用するように変更しています