Skip to content

Instantly share code, notes, and snippets.

@bhupal4all
Last active December 7, 2019 05:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bhupal4all/20b8c12122ff900ad4e9caf6a17caf36 to your computer and use it in GitHub Desktop.
Save bhupal4all/20b8c12122ff900ad4e9caf6a17caf36 to your computer and use it in GitHub Desktop.
Software Design Principles

SOLID Principles for Design

Intention


To make design to be more

  • Understandable
  • Easy to extend
  • Easy to Maintain, Refactor

SOLID is an acronym for 5 important design principles


  • Single Responsibility Principle - SRP
  • Open/Close Principle - OCP
  • Liksov Substitue Principle - LSP
  • Interface Segregation Principle - ISP
  • Dependency Inversion Principle - DIP

S ==> Single Responsibility Principle


A Class should have Only One reason to change. One Class for One Responsibility

  • Class is responsible for only one behavior/functionality
  • Below class 'Post' has functionality to post the message
    • Should do only posting the mesage
    • Shouldn't do logging the message to Database and this needs to be taken care of another class
class Post {
    public void postMessage(String message){
        // INFO: Only Message Post, No other responsibility 
        dao.post(message);

        // INFO: Writng the logging to database for future references
        // dao.logMessage(message); // <== Shouldn't do this, violates the (S) principle
        dbLogger.logMessage(message); // <== Here, DBLogger would take care of logging to DB
    }
}

O ==> Open/Close Principle


Open for extension & Close for modification

  • functionality can be extended through Inheritence and can be used by Polymorphism
  • if we need to provide or alter the functionality, create a new implementation instead of modifying existing
class Post {
  public void postMessage(String message) {
    /* 
    >> This shouldn't be here as voilates (O) Principle <<
    // INFO: If message starts with '#', create a tag instead of message
    if (message.startsWith('#')) {
      dao.postAsTag(message);
    } else {
      dao.post(message);
    }
    */
    
    // Post Message
    dao.post(message);
  }
}

class TagPost {
  public void postMessage(String message) {
    dao.postAsTag(message);
  }
}

L ==> Liksov Substitue Principle


Object should be substiuted with Object of their subtypes

  • S is sub type of T, then T object can be substituted with S object
  • Objects in the program should be replaced by instances of their subtypes without alerting the correctness of program
abstract class Post {
  public void postMessage(String message) {
    // default implementation if any
  }
}

class MessagePost extends Post {
  public void postMessage(String message) {
    dao.post(message);
  }
}

class TagPost: Post {
  public void postMessage(String message) {
    dao.postAsTag(message);
  }
}

class PostHandler {
  public void postMessage(String message) {
    Post post = null;
    
    if (message.startsWith('#')) {
      post = new TagPost();
    } else {
      post = new MessagePost();
    }
    
    post.postMessage(message); // <== We are not alerting the method call or logic 
  }
}

I ==> Interface Segregation Principle


No client should be forced to depend on the methods it doesn't use

  • To keep system decoupled and easier to refacter
  • Don't add additional functionality to existing interface, instead add a new interface
interface IPost {
  public void postMessage(String message);
}

interface IPostRead {
  public List<String> readMessage();
}

class PostImpl implements IPost, IPostRead { // <== Multiple Interface Implementations
  public void postMessage(String message) {
    // Implementation
  }
  
  public List<String> readMessages() {
    // Implementation
    return list;
  }
}

D ==> Dependency Inversion Principle


On should depend on Abstractions, not on Concretes

  • Typically, this is Dependency Injection
  • Abstractions shouldn't depend on details, But details should depend on Abstractions
class Post {
  IPostDAO dao;
  IDBLogger dbLogger;
  
  public Post(IPostDAO dao, IDBLogger dbLogger) { // <== Dependency Injection
    this.dao = dao;
    this.dbLogger = dbLogger;
  }

  public void post(String message){
    try {
      dao.post(message);
    } catch(Exception excp) {
      dbLogger.logException(excp);
    }
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment