Reputation: 5719
I am refactoring some old code and struck regarding a design decision
AbstractClassA
-Step 1
-Step 2
--Step 2.1
--Step 2.2
-Step 3
The above abstract class has abstract methods Step 1, Step 2 and Step 3. Step 2 always need to call methods 2.1 and 2.2. But in the current design, Step 2.1 and 2.2 are not declared as abstract and have been implemented and called in each and every inherited class. I am planning to refactor the code by pulling all these methods (including 2.1 and 2.2) into an interface. I am then planning to have abstract class implementation of this interface in which Step 2 would call 2.1 and 2.2. But somehow this doesn't seem neat. I want to know if this design is flawed?
InterfaceA
-Step1
-Step2
-Step 2.1
-Step 2.2
-Step3
Upvotes: 2
Views: 128
Reputation: 5567
It sounds like what you're looking for would be:
interface IMyInterface
{
void Step1();
void Step2();
void Step3();
}
abstract class MyBaseClass : IMyInterface
{
public abstract void Step1();
public void Step2()
{
Step2_1();
Step2_2();
}
public abstract void Step3();
protected abstract void Step2_1();
protected abstract void Step2_2();
}
Use an interface for abstraction, when you want to refer to something generically where the exact instance that will be used at runtime can change. Use a base class for shared implementation, so you can define what takes place in Step 2.1 and Step 2.2 in each subclass, but your base class defines that Step2 means execute Step 2.1 then Step 2.2.
Upvotes: 1
Reputation: 40336
So it seems like Step2 is part of the interface - that callers of this class expect to be able to call Step2. But that Step2.1 and Step2.2 are an implementation detail, something you don't want callers to see, although it will be implemented that way by all implementers of the interface - have I got that right?
If so, then I would have the interface include Step1, Step2, and Step3 (only). The abstract class would implement Step2 and further define protected Step2.1 and Step2.2, but define them as abstract, thereby forcing subclasses to provide implementations.
Unless you meant that Step2.1 and Step2.2 are identical in all subclasses, in which case I would make them private and place them in the abstract class.
Upvotes: 0
Reputation: 71565
Well, do you need the interface, or do you just think you do?
What I'm hearing is that you have AbstractClassA, which has two methods called by another method. If those two methods should be publicly accessible, then put them into the interface. If not, do not do so, and instead make them protected virtual or protected abstract in the abstract implementation of the interface.
Upvotes: 0
Reputation: 4891
The question you have to ask yourself if the implementations of Step 2.1 and Step 2.2 in the subclasses are specialisations or not, that is does it make sense for each the sub-class to implement its own step. If it does, then make them abstract. If it doesn't, use a common implementation and don't even make it virtual. If you do this it may well even be neat.
Upvotes: 0