Reputation: 15
I need some help building a fluent interface (class wrapper) that allows me to create (and name) a 2D double array from curve sets in a database (in myWell). Ideally, a user could create a 2D double array when executing the following syntax (or something similar):
Double [,] CurveDoubleName = CreateIPmathCurves.CreateCurve(comboBox1.Text).CurveName("NPHIL").Make()
Where comboBox1 data comes from a WindowsForm called frmMain. Here's what I have so far:
namespace UserProgram
{
public class CreateIPmathCurve : frmMain, ICanNameCurve, ICanLocateCurve, ICanMakeCurve
{
private string _comboBoxName;
private string _CurveName;
private string _data;
// Private constructor - Only allow instantiated functions to create an IP math Curve
private CreateIPmathCurve()
{ }
// Instantiating functions
public static ICanNameCurve CreateCurve()
{
return new CreateIPmathCurve();
}
// Chaining functions
private CreateIPmathCurve(string data) { _data = data; } //private constructor prevents instantiation of your builder
public ICanLocateCurve SetCurveName(string CurveName)
{
_CurveName = CurveName;
return this; // this allows chaining.
}
public ICanMakeCurve SetComboBoxName(string comboBoxName)
{
_comboBoxName = comboBoxName;
return this; // this allows chaining.
}
// ending functions
public DataObject CreateCurveDoublArrayObj(string comboBoxName)
{
try
{
// User will need to populate comboBox.. example: comboBox1.text
char[] delimiter = { ':' };
Curve1inText = comboBoxName;
string[] crvIn1 = Curve1inText.Split(delimiter);
string CurveSet = crvIn1[0];
string Curve = crvIn1[1];
ICurveSet InCurveSet = myWell.FindCurveSet(CurveSet);
ICurve InMyCurve = myWell.FindCurve(Curve);
if (InMyCurve == null)
{
MessageBox.Show("You need to input a curve");
}
ILogReading[] In = InMyCurve.LogReadings.ToArray();
double[,] CurveDouble = new double[In.Length, 2];
int j = 0;
foreach (ILogReading reading in InMyCurve.LogReadings)
{
CurveDouble[j, 0] = reading.Depth;
CurveDouble[j, 1] = reading.Value;
j++;
}
return new DataObject(CurveDouble);
}
catch (Exception ex)
{
MessageBox.Show("Error building Double Array\n" + ex.Message + "\n" + ex.StackTrace);
return null;
}
}
public double[,] MakeCurve()
{
//this is where CurveName input ("NPHIL") should name the 2D double array listed from dataobject.
// I receive a "non-invocable member 'DataObject' cannot be used like a method" error....
_CurveName = DataObject(_comboBoxName);
return this;
// I also receive a "cannot implicity convert type UserProgram.CreateIPmathCurve' to 'double [*,*]"...
}
}
// using interfaces to enforce Fluent Interface grammar -- can't make curve if you don't know the location of curve, etc...
public interface ICanNameCurve
{
ICanLocateCurve SetCurveName(string CurveName);
}
public interface ICanLocateCurve
{
ICanMakeCurve SetComboBoxName(string comboBoxName);
}
public interface ICanMakeCurve
{
DataObject CreateCurveDoublArrayObj(string comboBoxName);
}
}
Can you help me create a CurveName() function that would allow the user to name the dataobject? (I tried a getter-setter accessor, but I don't think I was doing it correctly or am lacking a strong conceptual understanding of how it all works)
Lastly, can you also help me create a Make() function that puts all of this together?
Upvotes: 0
Views: 111
Reputation: 15
I think I was over analyzing my problem - The simple solution would be to create a method that returns the 2D double array and then assign a name to the object when I invoke the function... so using this:
public double [,] CreateIPmathCurve(string comboBoxName)
{
string CurveInText = "";
char[] delimiter = { ':' };
CurveInText = comboBoxName;
string[] crvIn = CurveInText.Split(delimiter);
string CurveSet = crvIn[0];
string Curve = crvIn[1];
ICurveSet InCurveSet = myWell.FindCurveSet(CurveSet);
ICurve InMyCurve = myWell.FindCurve(Curve);
if (InMyCurve == null)
{
MessageBox.Show("You need to input a curve");
}
ILogReading[] In = InMyCurve.LogReadings.ToArray();
double[,] CurveDouble = new double[In.Length, 2];
int j = 0;
foreach (ILogReading reading in InMyCurve.LogReadings)
{
CurveDouble[j, 0] = reading.Depth;
CurveDouble[j, 1] = reading.Value;
j++;
}
return CurveDouble;
Allows me to create the array with this:
double[,] NPHIL = CreateIPmathCurve(comboBox1.Text);
Thanks to everyone who helped me in this endeavor!
Upvotes: 0
Reputation: 1992
To build a fluent API, you need to find a way to aggregate all data until your call to Make
.
A simple way is to write a Builder
, which holds all data. This builder has setter methods for every configurable field.
The key point here is that each setter method returns the Builder
object, allowing you to chain calls.
public class FluentCurveBuilder
{
private string _name;
private string _data;
private string _color;
private FluentCurveBuilder(string data) { _data = data; } // private constructor prevents instantiation of your builder
public FluentCurveBuilder SetName(string name)
{
_name = name;
return this; // this allows chaining.
}
public FluentCurveBuilder SetColor(string color)
{
_color = color;
return this; // this allows chaining.
}
public static FluentCurveBuilder CreateCurve(string data)
{
return new FluentCurveBuilder(data);
}
public Curve Make()
{
// Creation logic goes here
}
}
You now can use the builder to configure your curve.
var curve = FluentCurveBuilder.CreateCurve("Data")
.SetName("Test")
.Make();
We have a static CreateCurve
method, which returns a new builder. All other methods should only store the data in an instance field and return this builder.
In the Make
method, you now have access to all previous aggregated data and you can construct your Curve
Upvotes: 1