Click here to Skip to main content
15,881,424 members
Articles / Programming Languages / C#
Tip/Trick

Walking the System Design - II

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
2 Feb 2013CPOL8 min read 8K   4  
Walking the System design - II

Introduction

This tip is part of Walking the system design series. This is the second tip in the series. In this tip, I will share my recollected thoughts and experience around the design principles.

DRY

DRY or don’t repeat yourself. In my opinion, it is the father of all design principles. I am not an authority, but I feel that focusing on DRY is the pavement which takes you to the ultimate castle of design patterns. It is the starting point where someone starts recognizing the need of eliminating redundant code. I am not sure, but over the internet, I have read a quote with Bill Gates' photo next to it. I am not sure about the authenticity of it. I believe that a lazy person will find an innovative (easy) way to do the thing repeatedly. I also feel that DRY principle is the first choice to believe in. As per DRY, one should not be rewriting the same code again and again, one should write a piece of code once and only once.

What is the benefit of it? First of all, I believe that using DRY will automatically lead to a modular/object oriented/design based code, my belief stems from the fact that we are writing code only once, however we will definitely have multiple callers who are going to call this code, hence making the base for the reusability which is an attribute and fundamental principle behind well thought of structure code. The other benefit is, if there is any bug which appears later, we have one and only one place to fix it. We can also take into consideration the fact that multiple callers will require us to call the code in different ways (after all, all roads leads to Rome), which with practice will make us write code with less coupling and high cohesion.

Slow Moving and Fast Moving Code

In software, the code can be categorized into two broad categories, slow moving code and fast moving code. The slow moving code is generally the main function which calls the components to get its need fulfilled. The slow moving code seldom varies; the fast moving code varies very rapidly, e.g., a change in underlying API set, a change in persistent store. Fast moving code needs to wrapper around, so that its API usage is not permeated throughout the program. Fast moving code can be an abstract representation of required services. We need to fulfill the services using some particular implementation which may change during the course of our project, or may be changed in the future (Changes, tax and death are the only constant things in life).

One example of it could be the UX and the Data Access Layer (DAL). Though at the first it seems that UX is the fast moving code, however it is not. A UX is once defined and remains fixed for a while, a change in UX is also less frequent. Here UX is not the look and feel of the site. It is the task in hand which user is trying to accomplish. Whereas our DAL is fast moving code. DAL does not mean that we are going to access data from a database; it means we are going to touch some persistent store to fulfill our data needs. This store could be a web service, An XML file, a text file, a database (with all of its variants). Any code which uses third party API can also be categorized as Fast moving code.

We need to wrap the Fast moving code in some container and then use that container as a black box to fulfill the service requests originating from the slow moving code. The ideal situation will be to have a wrapper DLL dependency between the slow moving and fast moving code. The slow moving code (or the main program/UX layer) calls the well-defined PRO (I believe you remember this guy from the first article) without the intimate knowledge and gets its services fulfilled. Well this is a good thought in itself; we need to find out how to do this so that our Fast moving code can becomes plug and play module. We should be able to change to the new implementation or the new API without making many changes to the slow moving code. This will require us to take a dip in the Interfaces world.

A Glimpse into the World of Interfaces

Interface is a common life model being taken into computer science. In real life, we use interfaces so naturally that we don’t even know if we are using them. Just for fun, our home is an interface where we get shelter, food, clean clothes, and clean rooms with parental finances. In the same way, a hotel is an interface where we can get the above services but using our own finances (or may be use our father’s credit card). So as long as we as a service consumer are concerned, we only bother about the services we are looking for, we are not bothered about how these are going to fulfill. We can get the similar services in the hostel or PG or a rented accommodation. We might need to pay for them. Now let me introduce one problem, what if the services we need are known by different names, just because they are served by different people.

During my professional journey, I got a chance to relocate from North India to South India. India is big with lot of different languages. So my native language was not of much use in south India. I had to learn few words to get the basic necessities like water and food, by the way south Indian food is awesome (I prefer Hyderabad Biryani). Coming back to Computer Science, so what happens if we wrap the required services behind a common wrapper and everybody starts giving out different names to it. It is going to change our slow moving code every time we change the provider. For an analogy, we have a different word for ‘Water’ in Hindi and a different word for it in Telugu. This made me learn few new Telugu words.

This same learning will be required by our slow moving code if everyone starts providing the same service with a different name. Now interestingly to initially solve the language issue, I understood that we can show an empty glass (tumbler) and just make a gesture of sipping water, which will help the other person to understand that I am looking for water. We can try a similar thing in our code, so we not only wrap the fast moving code, but give a common function name to each service and every one should be using that name to fulfill the same required service. Thus making (forcing) a contract. In programming, we can translate this entire experience of creating a contract to the word “Interface”.

Interfaces can be used without the need to change the slow moving program every time a new implementation is implemented (use Unity for it, or may be few code changes in slow moving code). However this will require us to code the slow moving code in such a way that it is using interfaces for its required service fulfillment. We need to use the interface and code against its public methods. The next section talks in brief about code to interfaces not to implementation.

Code to Interfaces not to Implementations: My 2 Cents

Before we even start talking about it, we need to find out what is an implementation in technical terms. I will be using my little coding knowledge here for the benefit of readers.

I am basically a .NET programmer, so I would like to explain it using C#. In C#, an interface can be declared using the keyword “Interface”. Once we have declared an interface, we can add member functions to it (along with other things). These functions will not have any body; after all we are just trying to freeze the contract and want to be as much abstract as possible. We would like to handle the details of how it is being done using the implementations. We are trying to find out what needs to be done, the how part will be taken care of in the implementation.

An interface without any implementing class is not of much use. If we have an interface, we must have a class that is going to implement it. This implementing class is called Implementation. Now a slow moving code when using this class should not be creating using a reference of this class, rather it should be using the reference of interface, this way we can change the object creation and still our slow moving code will not be affected.

Interface

C#
Interface A
{
DoSomething();
}

Implementation

C#
Class A1 : A
{
DoSomething()
{
// body
}
}

Slow Moving code.

// Wrong way, Note the A1 (Implementation reference used to call DoSomething)
C#
A1 aobject = new A1();
Aobject.DoSomthing()
//Right way - Note the A (Interface reference used to call DoSomething)
C#
A aInterfaceReference = new A1();
aInterfaceReference.DoSomething();

Further Reading …

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
India India
A curious mind.

Comments and Discussions

 
-- There are no messages in this forum --