CodeSOD: Delebation
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.
[Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today!