How would you attack this construction problem with string polymorphism

Sorry for such an ugly name if someone wants to change it. Also note that I already asked a question about this, but it's more about how you attack it, because my attack just doesn't seem to be right.

I am having a problem constructing a string to send to an OLE object in the correct order using the polymorphism method in another question.

An OLE object can only accept and accept a string, so what I am doing is wrapping all common commands and providing more for them.

The problem I ran into very quickly was some of the commands that my wrapper had to send there for a very long time and have extra bits, which then suddenly turned the method that only set the name to a big string construction method, if given a name and of course this happens all over the place because there are many commands.

Now, to have a good wrapper, I would like to be able to complete the string construction process so that I move the string construction logic away from the wrapper itself and into the constructor object.
I tried to attack this using polymorphism, which works well when I have a building object class designed to only create one type of command line. See Other post for details.

Sorry for the long post, I'll get to the chase now.

The main problem is that many command lines need to be created, which means more constructor objects .
So, I'd love to have a generic string builder that can build a string from any list of commands, but the trick has to be in the correct order , even if the user sets them in the wrong order.

How do you approach this?

+1


source to share


1 answer


I think you are overcomplicating things and end up creating too many classes.

I would look at the problem as less string construction and more about how you present a good interface to the .net caller. Just because there are many possible arguments does not mean that you have to create many classes for them, at least if the possible variations within each argument are not very difficult, i.e. If the value is either there or not, and has additional devices. Then you get into this mess, requiring you to know the order that the parts of the command should have, etc.

I would probably create a class for the possible command arguments, whether the caller called whichever they like, and he has a class responsible for creating a string in one big (ugly?) String concatenation.

For example, I would start with something like this, and as you go, I would add methods where it makes sense to refactor a bit of string concatenation, depending on the similarity of the different parts of the command.

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 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) : "" )
         // ...
         ;
    }
}

      

If you prefer to use methods instead of properties, you can set value and units at the same time.



I would probably refactor this with the following methods immediately:

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

      

to make ToString () look like this:

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

      

then perhaps a similar method for positional arguments if there are more than one.

+1


source







All Articles