When faced with an API or programming paradigm that requires repetitive, boilerplate code, a developer is left with two options. They may refine or adapt the API/paradigm, using the idioms of their language to make something tedious and verbose into something elegant and clear.
Or they just automate it. If you have a mile of boilerplate that’s mostly the same across the application, just generate that. It’s like copy/paste, but, y’know… automatic.
Which is why Derf Skren found this pile in their codebase:
public abstract class ExchangeSingleData : IExchangeData
{
private readonly string mName;
private readonly int mLength;
private Dictionary<string, string> mMapValidData;
private byte[] mBuffer;
void AddValidValue(string name, string value) {
mMapValidData[name] = value;
}
//...
//...
}
public class NetChangeSign : ExchangeSingleData
{
public const string Plus = "+";
public const string Minus = "-";
public NetChangeSign()
: base("NetChangeSign", 1)
{
AddValidValue("Plus", Plus);
AddValidValue("Minus", Minus);
}
}
public class BidPriceSign : ExchangeSingleData
{
public const string Plus = "+";
public const string Minus = "-";
public BidPriceSign()
: base("BidPriceSign", 1)
{
AddValidValue("Plus", Plus);
AddValidValue("Minus", Minus);
}
}
public class AskPriceSign : ExchangeSingleData
{
public const string Plus = "+";
public const string Minus = "-";
public AskPriceSign()
: base("AskPriceSign", 1)
{
AddValidValue("Plus", Plus);
AddValidValue("Minus", Minus);
}
}
// ... and 7 more versions of the same class
The goal of this code is so that they can prepend a “+” or a “-” to a transaction’s value. Note the mBuffer
in the base class- they don’t use strings (or, y’know… numbers) to represent the transaction value, but a byte array instead. The “value” is that it lets them write a line like this:
lMessage.NetChangeSign.SetValue(GeneratePriceSign(lPrice));
Which allows the instance stored in NetChangeSign
to flip that +/- based on the return value of GeneratePriceSign
. Obviously, this lets the NetChangeSign
instance have full control of the logic of how the sign gets set, right? I mean, each instance has its own map that contains all the allowed values, right? Well… sure, but how do they decide? Based on GeneratePriceSign
… which looks like this:
private static string GeneratePriceSign(Side aSide)
{
if (aSide.Equals(Side.Buy))
return "+";
else
return "-";
}
In design patterns terms, we call this “delebation”. It’s like delegation, but only the person doing it to themselves enjoys it.