I\'ve got myself into a bit of a mess. I\'ve got code coming from Main, through
ID: 644467 • Letter: I
Question
I've got myself into a bit of a mess. I've got code coming from Main, through myMethod and down to OtherMethod. One of the parameters can be either an int or a string, which affects OtherMethod but none of the intervening methods.
public static void Main()
{
myMethod(number: 10);
myMethod(letters: "ten");
}
public static void myMethod(int number = 0, string letters = null)
{
//long entirely shared code with calls to:
OtherMethod(number,letters);
}
public static void OtherMethod(int number = 1, string letters = null)
{
//Lots of shared code, embedded multiple times within this code is essentially:
if (letters != null)
{
Console.WriteLine("letters!");
}
else
{
Console.WriteLine("numbers!");
}
}
OtherMethod cares about when I'm passing it int or string, but none of the intervening methods care. I would also find splitting OtherMethod without unnecessary code reuse very hard.
The solution I have provided works, but is probably an anti-pattern. Because, for example, a call to myMethod(10,"ten") would silently throw 10 in the bin.
Would changing it to private mymethod(int number = 0, string = null) called by public (int number) and public (string letter) for each level be a terrible idea?
I though of instead passing a class with both int and string and instructions of which to use right from the top to bottom. I suspect this is the solution. But it feels as OTT as it does OO.
My real use case is that I'm randomly generating data at the bottom of this chain and I can either provide a seed (int), or cheat and provide the data to generate (string). It occurs to me that what I'm doing may be a procedural dependency injection bodge,
Explanation / Answer
You are on the right track thinking you need to inject a class rather than the int and string parameters, but you actually want to inject one of two classes implementing a common interface: one with an int specialization and one with a string specialization.
To avoid the duplication in OtherMethod, you can make that common code that calls implementation-specific helper functions as necessary. In other words, wherever you have if (letters != null) put a call to HelperMethod().
I don't know C#, so consider this pseudocode, but it would look something like this:
public static void Main()
{
myMethod(new IntGenerator(10));
myMethod(new StringGenerator("ten"));
}
public static void myMethod(Generator gen)
{
//long entirely shared code with calls to:
gen.OtherMethod();
}
abstract class Generator {
abstract void HelperMethod();
public void OtherMethod()
{
//Lots of shared code, embedded multiple times within this code is:
HelperMethod();
}
}
class IntGenerator extends Generator
{
IntGenerator(int value) {}
void HelperMethod()
{
Console.WriteLine("numbers!");
}
}
class StringGenerator extends Generator
{
StringGenerator(string value) {}
void HelperMethod()
{
Console.WriteLine("letters!");
}
}
Yes, this creates a lot more functions, but if you divide it up properly, they are going to be much easier to maintain.
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.