Showing posts with label design principles. Show all posts
Showing posts with label design principles. Show all posts

26 June 2017

What is KISS principle

If you are working in IT industry, you might have heard your solutions architects & senior developers talking about KISS principle during solution design discussion. At least, I have heard it many times from my seniors and used it many times with my juniors. In this blog post let’s delve into, what is this KISS principle all about and why we need to care about it.

KISS expansion

KISS is an short for Keep it Simple, Stupid.

Let’s think you are proposing a new IT solution design. There could be many complicated scenarios in the business, but most of the common scenarios are simple. In this case, you should arrive at a simple solution to solve the problems instead of making it complex by considering all possible permutations and combinations. Every solution you propose needs not to solve 100% of the business cases. If it can just solve the pressing problems and it can be still very helpful for your customers.

Instead of keeping it simple, if you went onto cover all scenarios, you could end up with a complex solution which is difficult to use for the end users. Always make it simple for end users of your application.

If you think the solution is getting complicated, start having conversations with your business analysts and architects. Try to arrive at a solution to keep simple to use and simple to understand. Don't complicate solution just to cover some edge cases. The edge cases which are rare in nature can be handled separately as an exception.

KISS principle origin

As per Wikipedia, KISS is a design principle noted by the U.S. Navy way back in 1960.The KISS principle states that most systems work best if they are kept simple rather than made complicated; therefore simplicity should be a key goal in design and unnecessary complexity should be avoided.

Applying KISS principle outside engineering design solutions

I personally think, the KISS principle can be applied successfully in other fields well outside engineering and design.

For example, you could apply KISS principle to your investment strategy, instead of making it complex. The well-known stock investor Warren buffets says he keeps his investment philosophy simple and even then he is highly successful.

On the other hand, if you look at some investments funds which employ complex to understand investment philosophy are not that much successful.

So the essence here is, we should strive to keep the solutions SIMPLE from ALL the stakeholders perspective.

03 April 2015

dependency injection

While designing software systems, Architects press for loosely coupled software design. In this post let's see how to build loosely coupled class composition using dependency injection.

This blog post mainly aimed at explaining what is dependency injection with practical examples.

Code implemented without dependency injection

public class EmailManager
{
 public Send(Message message)
 {
  //Send email using SmtpClient
 }
}

You will use EmailManager class to send an email in your Client which probably looks something like below:

public class Client
{
   public void ProcessOrder(Order newOrder)
   {
    // Other business logic
    // Send email
    EmailManager mgnr = new EmailManager();
    manager.Send(message);
   }
}

Issues with code not using dependency injection

Above code will serve the purpose but there are two problems with code in the Client class.

  1. Cannot unit test ProcessOrder() method in the Client client.
  2. If requirements is changed from sending Email to text message, then you will have to modify Client class to use a new SMSManager instead of current EmailManager class. Changing an existing class to meet changing business requirement isn't always an option because of the regression involved. It violates OPEN for EXTENSION CLOSED for MODIFICATION design principle.

Refactor the code to eliminate design issues using Dependency injection

  • CHANGE #1:Changes to EmailManager class. Let's create a interface 'INotificationManager' and declare Send() method, later make the EmailManager to implement the interface.
  • CHANGE #2: Add a constructor to Client class to expect an object implementing INotificationManager interface

After the code refactoring the it will look like below:

public interface INotifictionManager
{
 void Send(Message message);
}

public class EmailManager:INotifictionManager
{
public void Send(Message message)
  {
    //logic to send email
   }
}

public class Client
{
  private INotificationManager _manager =null;
  public Client(INotifictionManager manager)
   {
    _manager =manager;
   }
   
  public void ProcessOrder(Order newOrder){
  {
    //..other logic...and build Message to be sent
    // send notification
    _manager.send(message);
  }
}

If you look at Client class in refactored code, its no longer creating an instance of EmailManager, that means it easy to unit the ProcessOrder() method using mocking.

Second, if in future business requirements changes from sending an email to sending a text message, then there will be no change in your client class. Instead of passing EmailManager instance, you will pass an instance of SmsTextManager class. That means there will be no change in your Client even if your requirement changes in future to send different type of notification.

If you have come so far reading the post and wondering where is the dependency injection, my answer is "You have already seen the dependency injection in the refactored code."

Finding what is dependency injection

Depedency Injection

The Client class need to send notification while processing an order. So The Client class has a dependency on the logic to send a notification. If you look at the refactored code, this logic is provided by INotifictionManager interface. So Client class has dependency on an instance of type INotifictionManager.

If you look carefully the Client class is not creating an instance of type INotifictionManager, instead of someone while instantiating Client is passing an instance of INotifictionManager type. So Client dependency on notification in being injected into it via INotifictionManager type. THIS IS CALLED DEPENDENCY INJECTION.