Refactoring a concrete method in an abstract class that contains an abstract method
Given the below code,
abstract class AbstractClass
{
public abstract void AbstractMethodA();
public void ConcreteMethodA()
{
//Some operation
ConcreteMethodB();
}
}
public void ConcreteMethodB()
{
//Huge code unrelated to this class
AbstractMethodA();
}
}
class DerivedClass : AbstractClass
{
public void AbstractMethodA()
{
//Some operation
}
}
Now I want to move ConcreteMethodB () to split the class and make a call to that from the ConcreteMethodA () method in the abstract class. But since ConcreteMethodB () uses the AbstractMethodA () method implemented in DerivedClass, I cannot access the AbstractMethodA () method from the new class? Any idea on how to resolve this?
source to share
Why don't you do it like this?
static class Helper {
public static void ConcreteMethodB(AbstractClass caller)
{
//Huge code unrelated to this class
caller.AbstractMethodA();
}
}
and then in AbstractClass
abstract class AbstractClass
{
public abstract void AbstractMethodA();
public void ConcreteMethodA()
{
//Some operation
Helper.ConcreteMethodB(this);
}
}
Editing, including a suggestion for an interface-based decoupling from David Arnault:
static class Helper {
public static void ConcreteMethodB(IAbstractClass caller)
{
//Huge code unrelated to this class
caller.AbstractMethodA();
}
}
interface IAbstractClass {
void AbstractMethodA();
}
and then in AbstractClass
abstract class AbstractClass
{
public abstract void AbstractMethodA();
public void ConcreteMethodA()
{
//Some operation
Helper.ConcreteMethodB(this);
}
}
This gives you better layer insulation. Of course, the solution proposed by David in his publication mentioning the use of "Action" and the passing method as an argument is also noteworthy.
source to share
To completely separate to two, you can take the "functional" route:
static class Helper
{
public static void ConcreteMethodB(Action caller)
{
//Huge code unrelated to this class
caller();
}
}
Changing AbstractClass to:
abstract class AbstractClass
{
public abstract void AbstractMethodA();
public void ConcreteMethodA()
{
Helper.ConcreteMethodB(AbstractMethodA);
}
}
source to share