ビルダーパターンのクラス構成
ビルダーパターンのクラス構成と、
実装方法を確認するため、
ファイル出力機能をビルダーパターンで作成しました。
まずは、ファイル出力機能で作成したクラスですが、
作成したクラスは、以下の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; } }