ビルダーパターンのクラス構成

ビルダーパターンのクラス構成と、
実装方法を確認するため、
ファイル出力機能をビルダーパターンで作成しました。

まずは、ファイル出力機能で作成したクラスですが、
作成したクラスは、以下の4種類のクラスになります。

1. クライアントクラス
ファイル出力処理の要求を行うクラス

2. ディレクタークラス
ファイル出力ビルダークラスのメソッドを使用して ファイルを出力するクラス

3. ファイル出力ビルダークラス
ファイル出力に必要な処理をまとめたクラスであり、
ファイル出力のための抽象化されたメソッドが定義されたクラス

4. ファイル出力サブクラス
ファイル出力ビルダークラスを継承したクラスであり、
実際のファイル出力処理が実装されているクラス。

次に、上記の4種類のクラスの構成についてですが、
上記の4種類のクラスは、以下のクラス図で記載した構成要素および関連を定義しています。

@startuml

class "Clientクラス"{
    +ファイル出力()
}

class "Directorクラス"{
    +ファイル出力(ファイル出力ビルダークラス)
}

class "ファイル出力ビルダークラス"{
    #ファイル出力パス : string [1]
    +ファイル出力場所の設定()
    +Excel出力データの生成()
    +CSV出力データの生成()
    +ファイル出力()
}

class "Excelファイル出力クラス"{
    +ファイル出力用データ : DataTable [1]
    +ファイル出力場所の設定()
    +Excel出力データの生成()
    +ファイル出力()
}

class "CSVファイル出力クラス"{
    +ファイル出力用データ : DataTable [1]
    +ファイル出力場所の設定()
    +CSV出力データの生成()
    +ファイル出力()
}

Clientクラス -right- Directorクラス
Clientクラス -right- Excelファイル出力クラス
Clientクラス -right- CSVファイル出力クラス
ファイル出力ビルダークラス <|-- Excelファイル出力クラス
ファイル出力ビルダークラス <|-- CSVファイル出力クラス

@enduml

最後に、実際に実装したソースコードを以下に記載します。
(C#による実装となっております)

1.クライアントクラス

public class ClientClass
{
    public DataTable OutputData { private get; set; }

    public void OutputCsvFile()
    {
        var director = new Director();
        var outputCsv = new OutputCsv();

        if(this.OutputData == null)
        {
            return;
        }

        // CSVファイル出力クラスへ出力データを設定する
        outputCsv.OutputFileData = this.OutputData;
        // CSVファイル出力クラスを引数として
        // ディレクタークラスのファイル出力メソッドを実行する
        director.OutoutFile(outputCsv);

        outputCsv.Dispose();
    }
}


2.ディレクタークラス

public class Director
{
    public void OutoutFile(OutputFileBase outputFileBuilder)
    {
        // ビルダークラスのメソッドを使用して、
        // ファイル出力処理を実行する
        outputFileBuilder.SetSaveFilePlace();
        outputFileBuilder.CreateOutputCsvData();
        outputFileBuilder.OutputFile();
    }
}


3.ファイル出力ビルダークラス

public class OutputFileBase
{
    protected string OutputFilePath { get; set; }
    protected List<string> OutputFileDataList { get; set; }

    // サブクラスで処理を実装するための、空の仮想メソッドを実装する
    public virtual void SetSaveFilePlace()
    {
    }

    public virtual void CreateOutputExcelData()
    {
    }

    public virtual void CreateOutputCsvData()
    {
    }

    public virtual void OutputFile()
    {
    }
}


4.ファイル出力サブクラス

public class OutputCsv:OutputFileBase,IDisposable
{
    private StreamWriter m_streamWriter;
    public DataTable OutputFileData { private get; set; }

    public override void SetSaveFilePlace()
    {
        var fileDialog = new SaveFileDialog();

        // ファイル保存ダイアログを表示		
        if(fileDialog.ShowDialog() == DialogResult.OK)
        {
            base.OutputFilePath = fileDialog.FileName;
        }

        m_streamWriter = new StreamWriter(base.OutputFilePath, false);
    }

    public override void CreateOutputCsvData()
    {
        if(this.OutputFileData == null)
        {
            return;
        }

        base.OutputFileDataList = new List<string>();
        var itemNum = this.OutputFileData.Columns.Count;

        foreach (DataRow row in this.OutputFileData.Rows)
        {
            var fileDataRow = new StringBuilder();

            for(var i = 0; i < itemNum; i++)
            {
                if(row[i] is string)
                {
                    fileDataRow.Append("\"");
                    fileDataRow.Append(row[i]);
                    fileDataRow.Append("\"");
                }
                else
                {
                    fileDataRow.Append(row[i]);
                }

                if(i < itemNum - 1)
                {
                    fileDataRow.Append(",");
                }
            }

            base.OutputFileDataList.Add(fileDataRow.ToString());
        }
    }

    public override void OutputFile()
    {
        foreach(var outputFileRow in base.OutputFileDataList)
        {
            m_streamWriter.WriteLine(outputFileRow);
        }
    }

    public void Dispose()
    {
        m_streamWriter.Close();
        m_streamWriter = null;
    }
}