1

抱歉,标题没有那么明显,如果有人想更改它,请继续。另请注意,我已经问过一个关于这种事情的问题,但这个问题更多的是关于你将如何攻击它,因为我的攻击似乎感觉不对。

我在构建一个字符串以使用另一个问题中的多态方法以正确的顺序发送到 OLE 对象时遇到问题。

OLE 对象只能接受和接收一个字符串,所以我正在做的是围绕所有常用命令构建一个包装器,并为它们提供更多的 .NET 感觉。

我很快遇到的问题是我的包装器必须发送的一些命令很长并且具有可选位,然后突然将一个只设置名称的方法变成了一个大字符串构建方法,if's just to set a name当然,这种情况无处不在,因为有很多命令。

现在,为了拥有一个好的包装器,我希望能够包装字符串构建过程,以便将字符串构建逻辑从包装器本身移到构建器对象中。
我试图通过使用多态性来解决这个问题,当我有一个专门为构建一种类型的命令字符串而设计的构建器对象类时效果很好。有关详细信息,请参阅其他帖子。

对不起,我现在要切入正题。

主要问题是必须构建大量命令字符串,这意味着更多的构建器对象
所以我真的很想有一个通用的字符串构建器,它可以从任何命令列表构建一个字符串,但问题是即使用户以错误的顺序设置它们,它们也必须按正确的顺序排列。

你会如何处理这个问题?

4

1 回答 1

1

我认为你把事情复杂化了,最终会创建太多的类。

我认为这个问题与其说是构建字符串,不如说是你如何为.net 调用者提供一个漂亮的接口。仅仅因为有很多可能的参数并不意味着你需要为它们创建很多类,至少如果每个参数中的可能变化不是很复杂,即如果值存在或不存在,并且有可选单位。然后你让自己陷入需要知道命令部分需要的顺序等的混乱中。

可能我会为命令的可能参数创建一个类,让调用者设置他们喜欢的任何参数,并让该类负责在一个大的(丑陋的?)字符串连接中生成字符串。

例如,我会从这样的东西开始,然后我会添加一些方法,根据命令不同部分的相似性,重构一些字符串连接是有意义的。

class CommandArgs 
{
    private double? _Position_x = null;
    private double? _Position_y = null;
    private String _Position_units = null;
    private double? _Width = null;
    private String _Width_units = null;
    private double? _Height = null;
    private String _Height_units = null;

    // maybe there's a better tuple-like type for this.
    public double[] Position 
    {
         set
         {
             if (value.length != 2) throw new ArgumentException("argh!");
             _Position_x = value[0];
             _Position_y = value[1];
         }
    }
    public string Position_Units
    {
         set
         {
             _Position_Units = value;
         }
    }
    public double Width
         set
         {
             _Width = value;
         }
    }
    public double Height
         set
         {
             _Height = value;
         }
    }
    public string Width_Units
         set
         {
             _Width = value;
         }
    }
    public string Height_Units
         set
         {
             _Height = value;
         }
    }
    // ....
    public override string ToString()
    {
         return 
             ( _Position_x != null ? string.Format(" Position ({0},{1})",_Position_x, _Position_y ) : "" )
             + ( _Height != null ? string.Format(" Height {0}")
                   + ( _Height_Units != null ? string.Format(" Units {0}", _Height_Units) : "" )
             + ( _Width != null ? string.Format(" Width {0}")
                   + ( _Width_Units != null ? string.Format(" Units {0}", _Width_Units) : "" )
         // ...
         ;
    }
}

如果您愿意,您可能希望创建方法而不是属性,因此您可以同时设置值和单位。

我可能会立即使用以下方法重构它:

private string FormatUnits(string units)
{
    return units == null ? "" : string.Format(" Units {0}", units);
}
private string FormatSingleValueArgument(string argName, object argValue, string units)
{
    if (argValue == null) return "";
    return string.Format(" {0} {1}", argName, argValue) + FormatUnits(units);
}

使 ToString() 看起来像这样:

         return 
             ( _Position_x != null ? string.Format(" Position ({0},{1})",_Position_x, _Position_y ) : "" )
             + FormatSingleValueArgument("Height", _Height, _Height_Units) 
             + FormatSingleValueArgument("Width", _Width, _Width_Units) 
         // ...
         ;

如果有几个类似位置的参数,那么也许可以为类似位置的参数做一个类似的方法。

于 2008-12-17T01:34:32.057 回答