你会如何攻击这种多态性字符串构建问题

时间:2008-12-17 01:17:50

标签: c# .net string polymorphism

很抱歉没有那么晦涩的标题,如果有人想改变它,请继续。还要注意我已经问了question关于这种事情,但是这个问题更多的是关于你如何攻击它,因为我的攻击似乎感觉不对。

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

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

我遇到的问题是我的包装器必须发送的一些命令很长并且有可选位然后突然变成了一个方法,只是将一个名称设置为一个大字符串构建方法,如果只是为了设置一个名称,当然这会发生在整个地方,因为有很多命令。

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

对不起,这篇长篇文章我现在要切入追逐。

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

你会怎么做?

1 个答案:

答案 0 :(得分: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) 
         // ...
         ;

然后可能为类似位置的参数做一个类似的方法,如果它们有几个。