0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

FactoryMethodを用いて、本番用と試験用のデータの使い分けを行う手法について

Last updated at Posted at 2024-09-14

初投稿です。
試験時にテストケースをいちいちデータベースに値を入れたり、通信を投げたりするのは非常に面倒です。今回はFactoryMethodを用いて本番用データとテスト用データを使い分ける方法を記します。サンプルコードはC#です。

FactoryMethodとは

  • クラスのインスタンスの生成の責務を「〇〇Factory」に負わせる手法です。
  • インスタンスを使う側のクラスは、コンストラクタを直接呼び出すのではなく、Factoryクラスのメソッドを呼び出し、その戻り値を利用します。

これにより、インスタンスを生成するときに行う処理をFactoryクラスの中で一元管理することができ、保守性が向上します。
ここでは、Factoryクラスでインスタンスを生成するときに、本番用とテスト用で扱うデータ様式を分岐する方法を紹介します。

サンプルの作成

ToDo(やりたいこと)

  • 例として、本番用のデータをSQLite、テスト用のデータをCSVで管理する
  • 素材の在庫状況を扱う「Materials」というデータ単位を対象とする
  • データクラスとして、MaterialEntityを作成する。
  • IMaterialRepositoryというインターフェースを作成し、Get()とSet()を定義する
  • インターフェースの実装クラスとして、MaterialSQLとMaterialFakeを作成する
  • 上記二つのクラスのインスタンスを生成する静的クラスとしてMaterialFactoryを作成し、CreateMaterial()を定義する
  • CreateMaterial()では、本番用かテスト用かによって、作成するインスタンスを分岐させるようにする

データの作成

カラムを左から、素材ID、素材名、在庫数とします。

本番用はSQLiteでMaterialsテーブルを作成します。
本番用テーブル作成.png
本番用テーブル.png

テスト用はMaterialFake.csvを作成します。
テスト用.png 

MaterialEntityの作成

データクラスのMaterialEntityを作成します。特に理由がない限りは完全コンストラクタ型にしておきます。

MaterialEntity.cs
namespace FactoryMethod
{
    // 素材のデータクラス
    public sealed class MaterialEntity
    {
        // コンストラクタ
        public MaterialEntity(int id, string name, int amount) 
        {
            Id = id;
            Name = name;
            Amount = amount;
        }

        // 素材ID
        public int Id { get; }

        // 素材名
        public string Name { get;}

        // 素材量
        public int Amount { get; }
    }
}

リポジトリのインターフェースを作成

IMaterialRepositoryを作成します。リポジトリは、「あるデータのやりとりにおける単位」という認識でOKです。例えるなら「入荷や配達を行う宅配便の配達員さん」みたいなもんです。
今回はこのインターフェースにSet()とGet()を定義します。適宜Update()やDelete()などを定義してもいいでしょう。

IMaterialRepository.cs
namespace FactoryMethod
{
    // 素材のリポジトリ
    public interface IMaterialRepository
    {
        // 素材の取得
        public MaterialEntity Get();

        // 素材の設定
        public void Set(MaterialEntity entity);
    }
}

実装クラスの作成

データを扱うクラスとして、本番用はMaterialSQLを、テスト用はMaterialFakeを作成します。それぞれインタフェースを実装させます。本番用はSQLを、テスト用はSystem.IOのファイル処理を用います。

MaterialSQL.cs(本番用)
namespace FactoryMethod
{
    internal class MaterialSQL : IMaterialRepository
    {
        public MaterialEntity Get()
        {
            //・・・(SQLの処理)
        }

        public void Set(MaterialEntity entity)
        {
            //・・・(SQLの処理)
        }
    }
}
MaterialFake.cs(テスト用)
namespace FactoryMethod
{
    internal class MaterialFake : IMaterialRepository
    {
        public MaterialEntity Get()
        {
            //・・・(CSVファイルの処理)
        }

        public void Set(MaterialEntity entity)
        {
            //・・・(CSVファイルの処理)
        }
    }
}

Factoryクラスの作成と生成するインスタンスの分岐

上記2つのクラスのインスタンスを生成する責務を担うMaterialFactoryを作成します。本番用の場合はMaterialSQLの、テスト用の場合はMaterialFakeのインスタンスを生成することとします。configファイルに設定値を待っても良いですし、DebugとReleaseの場合で分けても良いでしょう(今回は後者です)。

MaterialFactory.cs
namespace FactoryMethod
{
    public static class MaterialFactory
    {
        public static IMaterialRepository CreateMaterial()
        {
# if DEBUG
            return new MaterialFake();
#else
            return new MaterialSQL();
#endif
        }
    }
}

呼び出し

呼び出す側は、実装クラスを直接呼び出すのではなく、MaterialFactory.CreateMaterial()を呼び出し、IMaterialRepository型の変数に代入します。その変数からメソッドを呼び出して利用します。

MainClass.cs
namespace FactoryMethod
{
    public class MainClass
    {
        static void Main()
        {
            //本番時はMaterialSQLが、テスト時はMaterialFakeのインスタンスが生成される
            IMaterialRepository material = MaterialFactory.CreateMaterial();

            //Setメソッド
            material.Set(new MaterialEntity(4, "鉛", 500));

            //Getメソッド
            var entity = material.Get();
        }
    }
}

サンプルプログラムの作成は以上です。

メリット

  • 単体テストなどの机上デバッグを行う際に本番用のデータを扱う必要がないため、テストが効率化される。
  • データの様式が変わっても(データベースからjsonとか)、Repositoryインターフェースを実装させているデータのやり取りを行う箇所のみ変更すれば良いため、変更容易性が高い。

以上です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?