I want to clarify my use of the builder pattern, in particular how the type of builder is created. In examples, it just assumes the type of builder and creates it. However, I created a CreateBuilder method in a 'ChartBuilderFactory' class which returns the type of builder based on some object that was passed to it. Is this the best way of doing this? I've posted my sample code and would appreciate alternatives and suggestions for better design.
class Program
{
static void Main(string[] args)
{
DataObject data = new DataObject("basic", 2);
ChartDirector director = new ChartDirector();
ChartBuilderFactory builderFactory = new ChartBuilderFactory();
ChartBuilder builder = builderFactory.CreateChartBuilder(data);
director.Construct(builder);
Console.WriteLine(builder.GetChart());
Console.ReadKey();
}
}
class ChartBuilderFactory
{
public ChartBuilder CreateChartBuilder(DataObject data)
{
ChartBuilder builder;
if (data.DataType == "basic")
builder = new ChartBuilderBasic(data);
else if (data.DataType == "vector")
builder = new ChartBuilderVector(data);
else
builder = null;
return builder;
}
}
class ChartDirector
{
public void Construct(ChartBuilder builder)
{
builder.CreateChart();
builder.LoadData();
}
}
abstract class ChartBuilder
{
protected string myChartObject = "";
protected DataObject data;
public ChartBuilder(DataObject data)
{
this.data = data;
}
abstract public void CreateChart();
abstract public void LoadData();
public string GetChart() { return myChartObject; }
}
class ChartBuilderBasic : ChartBuilder
{
public ChartBuilderBasic(DataObject data)
: base(data) { }
public override void CreateChart()
{
myChartObject = "MyBasicChart";
}
public override void LoadData()
{
myChartObject += Convert.ToString(data.Data);
}
}
class ChartBuilderVector : ChartBuilder
{ /** Alternative Implementation here */ }
class DataObject
{
/** Constructor and private member variables here */
public string DataType { get { return this.dataType; } }
public int Data { get { return this.data; } }
}
I think you actually want is to use the Factory pattern to create the Builder classes. The Director does not create the Builder but has the dependency on them.
Have a look at this site which gives a good insight into patterns and uses some real example.
[EDIT : based on revised question]
Now that you have the creating of the Builders inside a factory you are set to go. If you want to remove the condition / finding of the correct builder there are a number of options depending on the size and complexity of the system.
The last 2 options might involve reflection (using the Activator class) in order to create the Builder class (or some Dependency Injection containers such as unity), but the exact mechanics are at least encapsulated inside the ChartBuilderFactory
Ideally if you use Dependency Injection (Inversion of Control) you are separating the construction of the objects from the way they are used. And if you centralize this it becomes easier to control and even change later if you need to. Not to mention making it easier to test.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With