Single Responsibility Principle – I Hate It

I am fond of Single Responsibility Principle.. But as the day passed I developed distaste for this principle. Why? The application I was working on grew with huge number of classes and interfaces. Code seemed like a spaghetti code. I started thinking that this principle instead of solving problems adding more to it. None the less the application became loosely coupled but grew into something that is difficult to understand. I would say the code became less cohesive. entangled wires

But I began realizing that the principle is not wrong, but the way I perceived it was wrong. When single responsibility says there should be one responsibility and one reason for change, the questions are

1. What is going to change?

2. What is the responsibility boundary? Is it class, collection of classes, module, collection of module?

If you take the WCF Service which serves product, is it not that the Product service following single responsibility?. When it changes it changes more for the reason that something related to product changed.

Or lets take an example of Employee detail. In order to display employee detail we go through employee UI, employee business layer, data access layer. Each layer is following SRP.

 If you take the employee detail class, you could have methods like GetJoiningDate, GetRelievingDate, GetPromotedDate, GetSalary, GetIncomeTaxOnSalary. All related to employee and I can argue that the only reason it could change is when I want to modify the employee related rules. That is perfectly normal.

And instead what I did is I over imagined that Dates and Salary are not same thing of an employee. Why not break it into EmployeeSalary and EmployeeChronology? We got 2 classes now. And when I am thinking in-terms of EmployeeSalary I feel that IncomeTax could be calculated annually and monthly. OOpss.. we need another class EmployeeIncomeTax.  Now we got 3 classes. Now employee could be rewarded with bonus. Argh.. Yes we need another class. EmployeeBonus. We made 4 classes. Employee could leave and we need to calculate his settlement and dues.. Ah.. Its a good idea to break it into another class EmployeeSettlement. We got 5 classes. See.. this is what happens when single responsibility boundary is not fixed :)

But notice that all these classes in reality are representing behaviors. Does this behavior change more often? Do you think you need to break classes this way where behavior wont change in another 100 years? Design principle says what changes should be kept apart from what doesn’t change.

If its not going to change then I am happy with Employee detail class. If the way the bonus is calculated more often changes , you got to change the logic more often, then move it apart.. How often bonus rules change is the call of the business.

Now easier it is to move the parts apart as long as you maintain unit tests. Otherwise you are on your own when playing something like this.

Thanks for reading.. Let me know your thoughts.

 

Writing Custom Framework – Good Or Bad

As per wiki framework is “an abstraction in which software providing generic functionality can be selectively changed by additional user-written code, thus providing application-specific software”  Interesting here is to see the word abstraction. What is abstracted by the software? 

Windows Communication Foundation (WCF) abstracts communication mechanism. Developer can use this framework to build applications which can talk to each other. WCF abstracted various communication mechanism such as MSMQ, HTTP, TCP. Also the framework addressed the concerns such as security, serialization that revolve around the communication requirements.

Similarly there are various frameworks for building UI such as MVC, ASP.NET, WPF so on. On top of these framework people try to write their own custom framework. Ofcourse the custom framework written on top of these various framework do fit the domain, but did anyone  consider the downside of it?

One of My experience with custom framework is awful. The framework offered nice features such as caching, hosting service and what not. I had installed windows azure bus on my machine. And the custom framework I was using started breaking. Having no clue and no one to go to, I had to debug into the framework code. I did find a place where this heavy weight custom framework is scanning all communication channels. Framework picked azure bus as its communication mode, and was missing configuration for it. I am sure the guys who wrote framework missed this scenario which could happen, and did not add configuration for it.  

What is the result of this mishap? The framework which is intended to reduce development time added hurdles to it. I spent first half of day contacting the framework developers, and then second half of day debugging the framework myself. 

The funny part is framework developers could not root cause the problem because there was no windows azure bus installed on their machine. More embarrassing is to say “it doesn’t work on my machine, but works everywhere else”

Like the framework definition goes the framework should solve the problem for only one abstraction (single responsibility). Does wiki say abstractionS? Should the framework choose the communication channel for the user, or user should choose the channel :)? 

 

Testable Objects

I have seen companies where unit testing is a theory than practice. Some think that creating a unit testing project in Visual Studio is unit testing.

What is unit testing then? Like a building constructed brick by brick, software is built with classes. Similar to faulty bricks can cause damage to the structure of the building, a badly written class can harm the application code.

I started my career writing bad code, and improved my coding style with constant learning under great Teachers. I know what is a bad code because I have written lot of it :D

So how do we write testable code?

Lets take a simple example of layered architecture which is very much prevalent in the industry. A three layer architecture will have Data Access Layer (DAL), Business Layer (BL) and Presentation Layer (PL).
So sample code looks like as shown below.


class Program
    {
        static void Main(string[] args)
        {
            PresentationLayer presentationLayer = new PresentationLayer();
            presentationLayer.Call();
        }
    }

    class PresentationLayer
    {
        BusinessLayer _businessLayer = new BusinessLayer();

        public void Call()
        {
            Console.WriteLine("Presentation Layer Called");
            _businessLayer.Call();
        }
    }

    class BusinessLayer
    {
        DataAccessLayer _dataAccessLayer = new DataAccessLayer();
        public void Call()
        {
            Console.WriteLine("Business Later Called");
            _dataAccessLayer.Call();
        }
    }

    class DataAccessLayer
    {
        public void Call()
        {
            Console.WriteLine("Data Access Layer Called");
        }
    }

Presentation layer makes a call to business logic layer, which in turn calls data access layer. Now unit testing means we should be able to test single functionality of one class. Can we test the call in business layer without having reference to data access layer? To make matter worse data access layer will mostly be written tightly coupled with database. So you can not test business layer until you have the  data access layer and database.

Still this is a not a convincing answer for having unit test? Then answer to question “how do you test all business scenarios around the BL?” could be more reasonable :)

Without unit test, business scenarios will be lost under the pile of code. And no one in the team can be sure that they did not break the component they touched.

To make the component testable one of the technique is to use Dependency Inversion Principle. With dependency inversion principle, we are going to compose the class as shown below.


class Program
    {
        static void Main(string[] args)
        {
            IDataAccessLayer dataAccessLayer = new DataAccessLayer();

            IBusinessLayer businessLayer = new BusinessLayer(dataAccessLayer);

            //We are composing the object
            PresentationLayer presentationLayer = new PresentationLayer(businessLayer);

            presentationLayer.Call();
        }
    }

    class PresentationLayer
    {
        IBusinessLayer _businessLayer ;

        public PresentationLayer(IBusinessLayer businessLayer)
        {
            _businessLayer = businessLayer;
        }

        public void Call()
        {
            Console.WriteLine("Presentation Layer Called");
            _businessLayer.Call();
        }
    }

    interface IBusinessLayer
    {
        void Call();
    }

    class BusinessLayer : IBusinessLayer
    {
        IDataAccessLayer _dataAccessLayer;

        public BusinessLayer(IDataAccessLayer dataAccessLayer)
        {
            _dataAccessLayer = dataAccessLayer;
        }

        public void Call()
        {
            Console.WriteLine("Business Layer Called");
            _dataAccessLayer.Call();
        }
    }

    interface IDataAccessLayer
    {
        void Call();
    }

    class DataAccessLayer : IDataAccessLayer
    {
        public void Call()
        {
            Console.WriteLine("Data Access Layer Called");
        }
    }

Our sample unit test around business layer with a stub data access layer is as shown below.


[TestClass]
    public class UnitTest1
    {
        public class DataAccessStub : IDataAccessLayer
        {
            public void Call()
            {
                Console.WriteLine("Data access stub called");
            }
        }

        [TestMethod]
        public void TestCall()
        {
            IDataAccessLayer dataAccessLayer = new DataAccessStub();

            IBusinessLayer businessLayer = new BusinessLayer(dataAccessLayer);

            businessLayer.Call();
        }
    }

Instead of using database dependent data access layer, we are using DataAccessLayerStub. We can now test all business scenarios around the business layer with the help dependency inversion principle.

I will explain more about stub in my next post. So keep watching :)

Tell, Dont Ask? Do we care?

Tell Don’t Ask Programming was something I never considered until I came across it.  I was designing the classes in a way I liked, without ground rules of OO programming.

Just like you got rules in every game, Object Oriented programming has its rules. One such rule is Tell Don’t Ask.

To give a background, lets take a problem. A software developer goes to his company. His Manager comes in, and asks him where is his computer. Then he asks him what are his log in credentials. Then he asks him how to write a program. Then he asks him how to compile it, and on and on. Basically Manager is taking up the developer’s  responsibility.

So our program looks like this.


    public class Manager
    {
        Developer _developer = new Developer();

        public void GetTheSoftwareProjectDone()
        {
            string loginName = _developer.LoginName;
            string computer = _developer.Computer;
            string programming = _developer.ProgrammingConstructs;
            string ideRules = _developer.IDERules;
            Console.WriteLine("Software written by Manager using all the above details from developer");
        }
    }

    public class Developer
    {
        public string LoginName { get; set; }

        public string Computer { get; set; }

        public string ProgrammingConstructs { get; set; }

        public string IDERules { get; set; }        
    }

Instead Manager should Tell developer to write the program instead of asking him too many questions :).  Developer’s reaction will be Tell, don’t ask :D

Lets illustrate it through the program.


    public class Manager
    {
        Developer _developer = new Developer();

        public void GetTheSoftwareProjectDone()
        {
           var software = _developer.WriteProgram();
        }
    }

    public class Developer
    {
        private string LoginName { get; set; }

        private string Computer { get; set; }

        private string ProgrammingConstructs { get; set; }

        private string IDERules { get; set; }

        public string WriteProgram()
        {
            Console.WriteLine("Software written by Developer using all the above details");
            return "Software";
        }
    }

Notice the details for writing the program is private to developer. Manager will tell the developer to write the software. Manager is only interested in the running software, and not the internal details of it. Developer writes the software and gives it to manager.

Best designed class will have high cohesion with all its responsibilities held in it. Internals of how it achieves this responsibility is not accessible to outside world.

Will discuss more rules in the coming posts. Let me know what you guys think :).

DDD – What is it?

Lots of buzz around DDD (Domain driven development). The concept most elaborately explained by Eric Evans in his book

I am not an expert in DDD, but have some feel of it which I would like to share here. Usual practice of web software development is 3 tier architecture. You got a business layer, data access layer and presentation layer. When developer writes code, he thinks only in terms of which table he is accessing, which component he is calling. This mental model of developer makes the real business cases invisible in the code. Code doesn’t reflect what business rule says. Eventually the business scenario will be lost under the code that no one can remember.

Not only helping preserve the business cases in the code, DDD helps developer and business speak the same language. Both communicate with each other using common language called ubiquitous language. Requirement gathering, and customer evaluations will be easy when both speak the same language.

DDD also helps in defining the boundaries across the domain using bounded contexts. Each context is bound for a given scenario. For example, customer is opening a savings account that is linked to his home loan account. There are two contexts

1. Customer opening a savings account

2. Customer’s home loan account

In the scenario when home loan is deducted from savings account, two contexts work with each other.  That makes both of them in one bounded context.

Similarly DDD will help in identifying the bounded contexts, which will help application maintenance and enhancements.

DDD helps work with domain objects. Domain objects are mostly the ones whose names are  nouns in the domain. For example if you say person is  a senior citizen, you can see two objects

1. Person

2. Citizen

Seniority can be treated as an attribute.

These are some of the things I could recollect from DDD. For more information and detail you can read the book by Eric Evans.  http://domaindrivendesign.org/books/evans_2003

Single Responsibility Principle

Since Object oriented represents some real world aspects, lets move away from OO for a moment. What is the single soul responsibility of Policeman? To stop crime.. What is the single soul responsibility of teacher? Teach children.

Teacher can not nab a thief. Its hard for Policeman to effectively teach children.

In reality, in object oriented world, this concept holds so much true. A class should have only one reason to change. If the policeman has to be promoted, its for only one reason. To stop more crime than before. If the teacher has to be promoted, its again to teach more subjects.

Lets take a bit more complex example. Bank provides savings account option to a customer. Bank has a rule that customer is treated as premier customer if the savings account balance is more than Rs 10,000. Thus our class looks like.

class SavingsAccount
{
    public decimal Balance { get; set; }

    public bool IsPremierCustomer()
    {
        return (Balance >= 1000);
    }

}

To encourage Premier customers bank is waiving the fee for online transactions. Now our class looks like as shown below.

class SavingsAccount
{
    public decimal Balance { get; set; }

    public bool IsPremierCustomer()
    {
        return (Balance >= 1000);
    }

    public void PerformTransaction()
    {
        if (IsPremierCustomer())
        {
            Console.WriteLine("Waiving transaction fee");
        }
    }
}

When we look at this class, it has two reasons to change in future. Bank may decide to include more customers to premier group by reducing the balance limit. Bank may waive the transaction fee for regular customers in future.

Also if you go by the rule of domain driven design, premier customer is something that represents a customer rule. Perform transaction represents monetary transaction. Waiving transaction is some kind of transaction again. Balance property stays in account class as this is the savings account balance.


public class BankProgram
{
   
    public static void Main(string[] args)
    {
        OnlineTransaction transaction = new OnlineTransaction();

        PremierCustomerRule customerRule = new PremierCustomerRule();

        SavingsAccount savingsAccount = new SavingsAccount(){ AccountNumber = "111", Balance = 1000};

        if (customerRule.OnAccountBalance(savingsAccount.Balance))
        {
            transaction.PerformTransactionWithNoFee();
        }
    }
 }


class PremierCustomerRule
{
    public bool OnAccountBalance(decimal  accountBalance)
    {
        return accountBalance >= 10000;
    }
}

class OnlineTransaction
{
    public void PerformTransactionWithNoFee()
    {
        //Fee waived    
    }
}


class SavingsAccount
{
    public string AccountNumber { get; set; }

    public decimal Balance { get; set; }
}

Here if you consider each class has one responsibility. PremierCustomerRule evaluates if customer is a premier customer based on account balance. OnlineTransaction has operation to perform transaction without fee. Savings account is a model that represents the customer account.

These classes with single responsibility are good candidates for unit testing. In future if the premier customer rule has to change it is only in one class. Same way all transaction types, with fee or without fee will go into OnlineTransaction class.

This is just an example of single responsibility principle, which can get more complicated as more business rules add up. If you notice I have a method called PerformTransactionWithNoFee. For normal customers we may need to introduce one more method PerformTransactionWithFee. Interesting thing to notice is that there are no if else clauses any where in the classes qualified for SRP, as against I could have said if premier customer then waive fee. Ofcourse this decision making is moved somewhere else, but not in the place where it violates single responsibility principle.

More interesting topics to come. Let me know what you guys think of SRP

How do you see objects? – Matrix way

Whenever I heard a question “what is an object?”, instant answer was “Instance of a class that represents real world entity”. Ah… how nice :)

But one day the question popped up in my mind “why object is called an object? why not tom or dick or harry?” :)  Following the question, a dialog from Matrix passed through my mind. “Everything has a purpose for existence”. The answer for object meaning lies in this statement. “Every living entity that has an objective is an object”.

Object is living? Yes, every bit of it.

  • Object has emotions which it will not express (Encapsulation).
  •  Object talks to other object (Method call).
  • Object has a memory like humans have brain (Data).
  • Object has a purpose or objective (service offered)
  • Object can have a child (inheritance)
  • Object can interpret same message differently (polymorphism)
  • Objects can be grouped into family (Class)
  • Child Object can have access to parent’s assets (inheritance)
  •  Finally object dies (Destructor).

Object should share information with its immediate friends, not to strangers. This is a kind of rule that one should follow, a rule stated as “Law of Demeter”.

Object can not kill itself as a rule. Same applies to humans which says “Never commit suicide”.

“Everything that has a beginning has an end”. Interesting isn’t it. I see objects as living entities. How do you guys think of it? Let me know :)