rkg
rkg

Reputation: 5719

Cleaner way of abstraction

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

Answers (4)

Joel C
Joel C

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

Carl Manaster
Carl Manaster

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

KeithS
KeithS

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

Aidan
Aidan

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

Related Questions