見出し画像

C#初心者を卒業しよう(第1回)Static Factory


はじめに

 オブジェクト指向は分かっている気でも、実際に使いこなせるかどうかは別の話だと思います。 もっと深く理解したいなら、デザインパターンを学んでみましょう。 初心者を卒業するにはもってこいなのではないかと思います。
 デザインパターンを個別に使うことはあまりないかもしれませんが、オブジェクト指向を学ぶのには非常に役立つ教材だと思います。 自分でいろいろなサンプルを作成し、練習することで使いこなせるようになるのが良い勉強法だと思います。
 ただし、デザインパターンについては多くの記事がありますので、簡単な説明にとどめます。 上手な説明がされている本やwebサイトを参考にしてください。
 このシリーズでは、簡単なプログラムから始めて徐々により良いプログラムにリファクタリングしていきます。

対象読者

 C#の文法をある程度学んだ人が対象ですが、それ程自信がなくても大丈夫だと思います。もし分からないところがあったら基本に戻れば良いだけです。是非チャレンジしてみてください。
 デザインパターンについて一度学んだことがあるが、途中で挫折してしまった人や、復習したい人にも役に立つと思います。

挫折しないために

 本やwebサイトで上手に説明されていても、私のように英語が苦手な人は、混乱して挫折してしまうかもしれません。英語で書かれた分かりやすいwebサイトはたくさんありますが、機械翻訳だと理解しにくく、挫折してしまった経験がある人もいるかもしれません。
 例えば、「Concrete Factory」を「コンクリート工場」と訳してしまうような機械翻訳はまだまだあるので、分かりやすい記事でも読みづらく感じることがよくあります。
 「concrete」はもちろん「コンクリート」ではなく、「具体的な」と訳すと分かりやすいのではないでしょうか。「具象」と訳されているものも多くありますが、これならなんとか理解はできるでしょう。同じ「concrete」を訳したものです。「Factory」は訳さなくても良いですね。
 サンプルプログラム中にも分からない単語があった時には辞書を引くことをお勧めします。多少面倒かも知れませんが理解の助けになることが良くあります。

開発環境

 開発環境は下記を使用しています。以前のバージョンの .NET ではインデントが深くなってしまったり、「using System;」などが必要だったりと肝心のプログラムが見づらくなってしまうので、このバージョンを使用しています。

  • .NET 8.0 

  • Visual Studio Code

Static Factory

 では早速 Static Factory をのサンプルを作ってみましょう。
 このパターンは、オブジェクト生成のロジックをカプセル化することで、コードの可読性と保守性を向上させられます。

プログラムの仕様

 これから作成するサンプルプログラムは、
「メートル」を「ヤード」に、
「ヤード」をメートルに
変換します。

 プログラムを起動すると、
「メートル」を「ヤード」に変換するか、
「ヤード」を「メートル」に変換するか
数字を入力して指定します。

 次に距離を入力すると、変換した距離をコンソールに出力して終了します。
 それぞれ入力に不備があった場合にはエラー終了します。

プログラムスケルトンの作成

 新しい開発用フォルダを作成し、「Visual Studio Code」を起動したら、「ファイル」メニューから「フォルダを開く…」を選択して開発用フォルダを開いてください。
 次に「control」+「@」キーで「ターミナル」を表示し、以下のコマンドを入力し、コンソールプログラムを作成してください。

dotnet new console

プログラムの作成

 「Hello World」を出力するプログラムを削除して、下記のプログラムを入力しましょう。
 入力が面倒ならコピーして貼り付けるか、ダウンロードしてください。但し、デバッガーで追いかけるなどして、このプログラムがどのように動作するのか理解してください。
 ここでは全体を見やすいように「Program.cs」に全て書いてしまっています。

Program.cs

Console.WriteLine("Please input convert number.");
Console.WriteLine("1 : Convert meters to yards.");
Console.WriteLine("2 : Convert yards to meters.");
if (!int.TryParse(Console.ReadLine(), out var convertNumber))
{
    throw new FormatException("Invalid input convert number.");
}
var distanceObject = DistanceFactory.Create(convertNumber);

Console.WriteLine("Please input distance.");
if (!double.TryParse(Console.ReadLine(), out var distance))
{
    throw new FormatException("Invalid input distance.");
}
distanceObject.Calculate(distance);

var outputMessage = distanceObject.CreateAnswerMessage();
Console.WriteLine(outputMessage);

public interface IDistance
{
    void Calculate(double distance);
    string CreateAnswerMessage();
}

public class DistanceFactory
{
    public static IDistance Create(int convertNumber)
    {
        switch (convertNumber)
        {
            case 1:
                return new ToYards();
            case 2:
                return new ToMeters();
            default:
                throw new ArgumentOutOfRangeException(
                    $"{convertNumber} is out of range.");
        }
    }
}

public class ToMeters : IDistance
{
    private double _yards;
    private double _meters;

    public void Calculate(double yards)
    {
        _yards = yards;
        _meters = yards / 1.0936133d;
    }

    public string CreateAnswerMessage()
    {
        return $"{_yards} yards is {_meters} meters.";
    }
}

public class ToYards : IDistance
{
    private double _yards;
    private double _meters;

    public void Calculate(double meters)
    {
        _meters = meters;
        _yards = meters * 1.0936133d;
    }

    public string CreateAnswerMessage()
    {
        return $"{_meters} meters is {_yards} yards.";
    }
}

ダウンロード

 ダウンロード用に置いてあるものは、クラスごとにファイルを分けてあります。

実行

デバッグ

 プログラムを停止したい行の左端をクリックすると赤丸がついてブレイクポイントが設定出来ます。解除はこの赤丸をクリックします。
 ブレイクポイントを設定したら「実行」メニューから「デバッグの開始」を選択するか、画面左側の「実行とデバッグ」アイコンをクリックしてください。

実行

 プログラムの実行は「ターミナル」で以下のコマンドを打つか、「実行」メニューから「デバッグなしで実行」を選択します。

dotnet run

練習問題

 より理解を深めるために、以下の練習問題に取り組んでみてください。

練習問題 01

 このサンプルプログラムに
「メートル」を「フィート」に、
「フィート」を「メートル」に
変換できる機能を追加してください。

おわりに

 次回は、このサンプルを Factory Method に書き直して、もう少し良くしていきます。お楽しみに。

 


よろしければサポートをお願いします。 いただいたサポートは、書籍代、開発機器購入などに充てさせていただきます。