Wednesday, February 25, 2015

Implementing Interface in C#


I have been programming for my living for quite few years, programming is more like hobby and sometime one of the way to past time, like gaming. Uncle Bob forwarded something called SOLID for good object oriented design and sometime we do blindly follow it sometime we really need it. Today I have something for Interface Segregation.
Interface has been around for quite a while from java to now typescript. Yes its basically a contract as defined on papers about interface but why do we need a contract? how do we implement it in real world application? There are enough Foo and Bar around, knowing technical part of it, knowing syntax is the most easiest part of anything along with how to do :-), but actually getting your finger to write code along with interface takes time.

Let us assume I have class FoodEstablishment, now I want to do simple CRUD operation, so how do I do it?
I define an interface for service, but why? wait :-)

public interface IFoodEstablishmentService
{
    Task<int> AddAsync(FoodEstablishment oFoodEstablishment);
    FoodEstablishment SelectByFoodEstablishmentId(long id);
    Task<int> UpdateAsync(FoodEstablishment oFoodEstablishment);
    Task<int> DeleteAsync(FoodEstablishment oFoodEstablishment);
}

Then I will implement that contract or interface for that particular service

public class FoodEstablishmentService : IFoodEstablishmentService
{
    public async Task<int> AddAsync(FoodEstablishment oFoodEstablishment)
    {
       // Insert Operation
        return result;
    }

    public FoodEstablishment SelectByFoodEstablishmentId(long id)
    {
        // Select Logic
        return oFoodEstablishment;
    }

    public async Task<int> UpdateAsync(FoodEstablishment oFoodEstablishment)
    {
        // Update Logic
        return result;
    }

    public async Task<int> DeleteAsync(FoodEstablishment oFoodEstablishment)
    {
        // Delete Logic
        return result;
    }
}

So in my main program or where I wish to use Service, I will do

IFoodEstablishmentService oFoodEstablishmentService =  new FoodEstablishmentService();
FoodEstablishment oFoodEstablishment = // Input might be from views;
oFoodEstablishmentService.AddAsync(oFoodEstablishment);

So till now it seems like an extra step, when we could have directly done

FoodEstablishmentService oFoodEstablishmentService =  new FoodEstablishmentService();
FoodEstablishment oFoodEstablishment = // Input might be from views;
oFoodEstablishmentService.AddAsync(oFoodEstablishment);

But wait what if I might need to pass my insert logic through queue rather than directly to server, wait for insert operation to complete and then return result, rather pass on queue and then the queue worker handles those operation, might not be best idea to queue insert but yes definitely good for interface example :-). So now what I do is, create another class FoodEstablishment implementing same contract IFoodEstablishment.

public class FoodEstablishmentQueueService : IFoodEstablishmentService
{
    public async Task<int> AddAsync(FoodEstablishment oFoodEstablishment)
    {
       // Insert Queue Operation
        return result;
    }

    public FoodEstablishment SelectByFoodEstablishmentId(long id)
    {
        // Select Queue Logic
        return oFoodEstablishment;
    }

    public async Task<int> UpdateAsync(FoodEstablishment oFoodEstablishment)
    {
        // Update Queue Logic
        return result;
    }

    public async Task<int> DeleteAsync(FoodEstablishment oFoodEstablishment)
    {
        // Delete Queue Logic
        return result;
    }
}

So now if I want to use the queue version, I would just do

IFoodEstablishmentService oFoodEstablishmentService =  new FoodEstablishmentQueueService();
FoodEstablishment oFoodEstablishment = // Input might be from views;
oFoodEstablishmentService.AddAsync(oFoodEstablishment);

We could do that with the older way using class but that bounds the class instantiation with a particular class which is kind of rigid to extension, now FoodEstablishmentQueueService can do other things too, create another method until the contract is valid so interface is contact for consistency, Imaging one guy doing the normal version and other doing the queue version or someone doing cache version, there might be problems regarding signature unless its pre-specified about the working contract and people don't end up cross checking everything.

Similarly, let consider other simple example of using predefined types like IEnumerable. Suppose I pass a list of FoodEstablishment collection and return custom sorted list

public FoodEstablishment[] SortFoodEstablishment(FoodEstablishment[] list)
{
    foreach(var oFoodEstablishment in list)
    {
    // some logic
    }
    return sortedList;
}

So we will use it this way

FoodEstablishment[] list = new FoodEstablishment[]{ //some values }
var listSorted = oFoodEstablishmentService.SortFoodEstablishment(list);

But what if we send list instead of array

List<FoodEstablishment> list = //some values;
var listSorted = oFoodEstablishmentService.SortFoodEstablishment(list);

We will get error, because its strict implementation using class so instead we use IEnumerable<> which is implemented by List and that basically removes dependency from List to Interface

public IEnumerable<FoodEstablishment> SortFoodEstablishment(IEnumerable<FoodEstablishment> list)
{
    foreach(var oFoodEstablishment in list)
    {
    // some logic
    }
    return sortedList;
}

So usually implementation hugely depends on situation, its not like I woke up suddenly and start writing everywhere :-)

I am getting really hungry and more foolish than ever :D

No comments :

Post a Comment