【问题标题】:Class wrapper for data lists数据列表的类包装器
【发布时间】:2017-09-11 14:53:02
【问题描述】:

我需要一些帮助来构建一个流畅的接口(类包装器),它允许我从数据库(在 myWell 中)中的曲线集创建(和命名)一个二维双数组。理想情况下,用户可以在执行以下语法(或类似语法)时创建一个二维双精度数组:

 Double [,] CurveDoubleName = CreateIPmathCurves.CreateCurve(comboBox1.Text).CurveName("NPHIL").Make()

comboBox1 数据来自名为 frmMain 的 WindowsForm。到目前为止,这是我所拥有的:

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);
    }

}

你能帮我创建一个允许用户命名数据对象的 CurveName() 函数吗? (我尝试了一个 getter-setter 访问器,但我认为我做的不正确,或者对它的工作原理缺乏深刻的概念理解)

最后,您能否帮我创建一个 Make() 函数将所有这些组合在一起?

【问题讨论】:

  • 这称为fluent interface。对于初学者来说可能有点太高级了。为什么不从普通的方法/属性开始?
  • 你想要达到的结果是什么?双精度数组仅包含双精度值。所以没有办法命名或定位你的曲线。
  • DataObject CreateCurveDoubleArray 从我的井数据库中找到曲线(使用组合框输入)并填充一个名为 CurveDouble 的 2D 双精度数组。我想将这个新的 2D 双精度数组分配给一个名称(由曲线名称)。我希望语法简单一些,类似于上面的语法( CreateIPmathCurves.CreateCurve(comboBox1.Text).CurveName("NPHIL").Make() )

标签: c# .net oop


【解决方案1】:

要构建流畅的 API,您需要找到一种方法来聚合所有数据,直到您调用 Make

一个简单的方法是写一个Builder,它保存所有的数据。该构建器为每个可配置字段提供了 setter 方法。

这里的重点是每个setter方法都返回Builder对象,让你可以链式调用。

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
    }
}

您现在可以使用构建器来配置您的曲线。

var curve = FluentCurveBuilder.CreateCurve("Data")
                              .SetName("Test")
                              .Make();

我们有一个静态的CreateCurve 方法,它返回一个新的构建器。所有其他方法应仅将数据存储在实例字段中并返回此构建器。

Make 方法中,您现在可以访问所有以前的聚合数据,并且可以构造您的Curve

【讨论】:

  • 谢谢lqon,这已证明可以帮助我更接近可行的解决方案。我已经更新了我的问题,代码(上面)你能看看我错过了什么吗?
【解决方案2】:

我想我过度分析了我的问题 - 简单的解决方案是创建一个返回二维双精度数组的方法,然后在我调用函数时为对象分配一个名称......所以使用这个:

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;

允许我用这个创建数组:

double[,] NPHIL = CreateIPmathCurve(comboBox1.Text);

感谢所有帮助我完成这项工作的人!

【讨论】:

    猜你喜欢
    • 2019-11-26
    • 2010-11-18
    • 2018-10-10
    • 1970-01-01
    • 2016-02-03
    • 1970-01-01
    • 2012-04-11
    • 2022-10-25
    • 2015-01-25
    相关资源
    最近更新 更多