A pattern that I do quite often is to first right out code that actually works, then when I see a pattern repeat itself, I like to refactor that code to try and avoid the repetitive code. Reasons include:
- Smaller Code
- Less Chance For Error
- Don’t Repeat Yourself (DRY)
As an example, the c# code I’m working on now involves reading key values to be used with the Stripe payment service. Here is the code I first wrote:
bool testMode = Utils.AppSettingCheck("StripeTestMode", null, null, codeCampYearId, null);
// don’t even set values
if (testMode)
{
// test
var stripeTestSecretKey = Utils.AppSettingValue(“StripeTestSecretKey”, null, null, codeCampYearId, null);
if (String.IsNullOrEmpty(stripeTestSecretKey))
{
view.StripePublicAndPrivateKeys.StripeSecretKey = Utils.AppSettingValue(“StripeTestSecretKey”,
null, null, codeCampYearId, null);
}
else
{
view.StripePublicAndPrivateKeys.StripeSecretKey = Utils.AppSettingValue("StripeTestSecretKey",
null, null, 999, null);
}
var stripePublicKey = Utils.AppSettingValue("StripePublicKey", null, null, codeCampYearId, null);
if (String.IsNullOrEmpty(stripePublicKey))
{
view.StripePublicAndPrivateKeys.StripePublicKey = Utils.AppSettingValue("StripeTestPublicKey",
null, null, 999, null);
}
}
else
{
// live
var stripeLiveSecretKey = Utils.AppSettingValue(“StripeLiveSecretKey”, null, null, codeCampYearId, null);
if (String.IsNullOrEmpty(stripeLiveSecretKey))
{
view.StripePublicAndPrivateKeys.StripeSecretKey = Utils.AppSettingValue(“StripeLiveSecretKey”,
null, null, 999, null);
}
var stripePublicKey = Utils.AppSettingValue("StripeLivePublicKey", null, null, codeCampYearId, null);
if (String.IsNullOrEmpty(stripePublicKey))
{
view.StripePublicAndPrivateKeys.StripePublicKey = Utils.AppSettingValue("StripeLivePublicKey",
null, null, 999, null);
}
}
The first thing I do is to look for the pattern and try and pull out variables that I know are going to be helpful in refacotring. You can see below that I pulled out the keyAppName variable and I also changed the assignment to be to a new variable rather than to the exact target I wanted (keyValue instead of view.StripePublicAndPrivateKeys.StripeSecretKey). The reason is my plan is to pull out the common functionality and to do this I don't want to have to pass into a common method lot's of extranious classes.
if (testMode)
{
// test
var keyAppName = "StripeTestSecretKey";
var keyValue = Utils.AppSettingValue(keyAppName, null,
null,
String.IsNullOrEmpty(Utils.AppSettingValue(keyAppName, null, null, codeCampYearId, null))
? codeCampYearId
: 999, null);
view.StripePublicAndPrivateKeys.StripeSecretKey = keyValue;
var stripePublicKey = Utils.AppSettingValue("StripePublicKey", null, null, codeCampYearId, null);
if (String.IsNullOrEmpty(stripePublicKey))
{
view.StripePublicAndPrivateKeys.StripePublicKey = Utils.AppSettingValue("StripeTestPublicKey",
null, null, 999, null);
}
}
Next, through the helpfulness of JetBrain's ReSharper, I select the code I want to refactor and then right mouse button, say "Extract Method" and this is what I get:
The method that is created is this:
Which, when shown, changes the code to the following (notice that the method GetKeyValueFromStrip is created.
var keyAppName = "StripeTestSecretKey";
var keyValue = GetKeyValueFromStrip(codeCampYearId, keyAppName);
view.StripePublicAndPrivateKeys.StripeSecretKey = keyValue;
And, that can be simplified to simply
view.StripePublicAndPrivateKeys.StripeSecretKey =
GetKeyValueFromStrip(codeCampYearId, "StripeTestSecretKey");
And now, all 4 keys (public and private for both live and test) can be generated quite simply and with little chance of typos as follows
if (testMode)
{
view.StripePublicAndPrivateKeys.StripeSecretKey =
GetKeyValueFromStrip(codeCampYearId, "StripeTestSecretKey");
view.StripePublicAndPrivateKeys.StripePublicKey =
GetKeyValueFromStrip(codeCampYearId, "StripeTestPublicKey");
}
else
{
view.StripePublicAndPrivateKeys.StripeSecretKey =
GetKeyValueFromStrip(codeCampYearId, "StripeLiveSecretKey");
view.StripePublicAndPrivateKeys.StripePublicKey =
GetKeyValueFromStrip(codeCampYearId, "StripeLivePublicKey");
}
}
private static string GetKeyValueFromStrip(int codeCampYearId, string keyAppName)
{
var keyValue = Utils.AppSettingValue(keyAppName, null,
null,
String.IsNullOrEmpty(Utils.AppSettingValue(keyAppName, null, null, codeCampYearId, null))
? codeCampYearId
: 999, null);
return keyValue;
}