user3289921
user3289921

Reputation: 93

c# interface segregation principle example confusion

I'm fairly new to programming and i'm having trouble to understand how to apply effectively the principle showed in the following link (the ATM one):

http://www.objectmentor.com/resources/articles/isp.pdf

Basically it starts with a design that does not complain the ISP (Interface Segregation Principle), and moves forward to refactor the behavior into different interfaces.

My question is: Don't we use interfaces to express common behaviour among not so (or not) related abstractions?

What's the point of encapsulating methods in an interface, if not even one is going to be shared with the classes that are going to implement them? In which scenario this could be consider useful?

If we continue the line of the example, the following code is given:

public interface ITransaction
{
    void Execute();
}

public interface IDepositUi
{
    void RequestDepositAmount();
}

public class DepositTransaction : ITransaction
{
    private IDepositUi depositUI;

    public DepositTransaction(IDepositUi ui)
    {
        depositUI = ui;
    }

    public virtual void Execute()
    {
        /*code*/
        depositUI.RequestDepositAmount();
        /*code*/
    }
}

public interface WithdrawalUI
{
    void RequestWithdrawalAmount();
}

public class WithdrawalTransaction : ITransaction
{
    private WithdrawalUI withdrawalUI;

    public WithdrawalTransaction(WithdrawalUI ui)
    {
        withdrawalUI = ui;
    }

    public virtual void Execute()
    {
        /*code*/
        withdrawalUI.RequestWithdrawalAmount(); /*code*/
    }
}

public interface TransferUI
{
    void RequestTransferAmount();
}

public class TransferTransaction : ITransaction
{
    private TransferUI transferUI;

    public TransferTransaction(TransferUI ui)
    {
        transferUI = ui;
    }

    public virtual void Execute()
    {
        /*code*/
        transferUI.RequestTransferAmount();
        /*code*/
    }
}

public interface UI : IDepositUi, WithdrawalUI, TransferUI
{
}

As far as i understand this, in order to use the previous design we should have something like:

UI impui = new IMPLEMENTATIONUI(); // Some UI implementation
DepositTransaction dt = new DepositTransaction(Gui);
dt.Execute();

Now, wouldn't we need that the IMPLEMENTATIONUI implements every single method? And if so, wouldn't it break the SRP?.

Upvotes: 4

Views: 1271

Answers (2)

Scott Hannen
Scott Hannen

Reputation: 29207

Is having one interface inherit from three others an ISP violation?

public interface UI : IDepositUi, WithdrawalUI, TransferUI
{
}

The answer is that we can't tell. It depends on whether or not the client depends on the entire interface. If it does then this is not an ISP violation. If the client doesn't depend on all three inherited interfaces then this is a violation and the client should just depend on whichever interface(s) it does need.

It might, as you observed, violate some other principle, but that would be outside of the scope of discussing the ISP. But I don't think the point is that you should create that combined interface. The point is that you can while still preserving the smaller, segregated interfaces.

We might be tempted to create on giant interface and one giant class just because one client depends on all three interfaces. But if we do that, another client that only needs withdrawals or transfers would be forced to depend on the larger interface that it doesn't need.

In real life this sort of thing grows out of control because someone starts off with broad, vaguely named interface like ITransactionService and before you know it more developers throw the kitchen sink into it. In the example the interfaces are more specifically named. That won't enforce keeping them segregated, but it helps. Giving them such specific names up front communicates what should or shouldn't be in them. It suggests a developer who planned up front to keep interfaces segregated.

Upvotes: 0

Kyle B
Kyle B

Reputation: 2889

Don't we use interfaces to express common behaviour among not so (or not) related abstractions?

Yes, in SOLID, interfaces are required to express common behavior. Your Transaction interface is a superb example of this. Both the DepositTransaction and WithdrawlTransaction classes depend on it. ISP (Interface Segregation Principle) wants you to split this out because you may have a need to pass a Transaction object into a function to execute it. All of the SOLID principles are designFor example:

void ExecuteTransaction(Transaction transaction)
{
    transaction.Execute();
}

Please note that this method does not depend on anything but the Transaction interface. This is dependency inversion.

If you do not create this interface you would need to create two different methods for executing a WithdrawlTransaction or a DepositTransaction; instead, you can use the ExecuteTransaction method and pass in anything that implements Transaction.

ExecuteTransation(withdrawl_TransactionObject);

or

ExecuteTransaction(deposit_TransactionObject);

or later in the future:

ExecuteTransaction(unanticipatedNewTypeOf_TransactionObject);

Now, wouldn't we need that the IMPLEMENTATIONUI implements every single method? And if so, wouldn't it break the SRP?

The Implementation UI is probably what the user uses to interact with the software. The user won't have a Single Responsibility, theoretically he/she will have to use all the interfaces that are required for the IMPLEMENTATIONUI class.

I doubt the implementation UI would implement all of the interfaces but it would likely use all of these interfaces in order to execute transactions. To paraphrase "Uncle Bob" Solid Principles your user interface should be full of Volatile code while your interfaces should be the most non-volatile.

Upvotes: 1

Related Questions