Sunday, May 12, 2019

SOLID PRINCIPLES IN JAVA

5 java class design principles

  1. Also refer :https://www.baeldung.com/solid-principles

  2. https://dzone.com/articles/solid-principles-by-examples-single-responsability?fromrel=true

    https://dzone.com/articles/solid-principles-by-examples-openclosed

    https://dzone.com/articles/solid-principles-by-examples-liskov-substitution-p

    https://dzone.com/articles/solid-principles-by-example-interface-segregation

    https://dzone.com/articles/solid-principles-by-example-dependency-inversion

    For All 10 design principles

  3. 1)Single Responsibility

  4. The name of the principle says it all:
    “One class should have one and only one responsibility”
    In other words, we should write, change and maintain a class for only one purpose. If it is model class then it should strictly represent only one actor/ entity. This will give we the flexibility to make changes in future without worrying the impacts of changes for another entity.

    Similarly, If we are writing service/manager class then it should contain only that part of method calls and nothing else. Not even utility global functions related to module. Better separate them in another globally accessible class file. This will help in maintaining the class for that particular purpose, and we can decide the visibility of class to specific module only.

  5. How does this principle help us to build better software? Let’s see a few of its benefits:
    1. 1)Testing – A class with one responsibility will have far fewer test cases

    2. 2)Lower coupling – Less functionality in a single class will have fewer dependencies

    3. 3)Organization – Smaller, well-organized classes are easier to search than monolithic ones

    In our application level code, we define model classes to represent real time entities such as person, employee, account etc. Most of these classes are examples of SRP principle because when we need to change the state of a person, only then we will modify a person class. and so on.
    In given example, we have two classes Person and Account. Both have single responsibility to store their specific information. If we want to change state of Person then we do not need to modify the class Account and vice-versa.

    If you put more than one functionality in one Class in Java it introduces coupling between two functionality and even if you change one functionality there is a chance you broke coupled functionality,  which requires another round of testing to avoid any surprise on the production environment.
    Person.java
    public class Person
    {
        private Long personId;
        private String firstName;
        private String lastName;
        private String age;
        private List<Account> accounts;
    }
    Account.java
    public class Account
    {
        private Long guid;
        private String accountNumber;
        private String accountName;
        private String status;
        private String type;
    }

    2)O is for Open/Closed Principle


    This is second important rule which we should keep in mind while designing our application. Open closed principle states:

    “Software components should be open for extension, but closed for modification”

    What does this mean?? This means that our classes should be designed such a way that whenever fellow developers wants to change the flow of control in specific conditions in application, all they need to extend our class and override some functions and that’s it.

    Give example of Stratergy design pattern:


    Strategy design pattern is based upon open closed design principle



    eg1:
    If we take a look into any good framework like  spring, we will see that we can not change their core logic and request processing, but we modify the desired application flow just by extending some classes and plugin them in configuration files.
    For example, spring framework has class DispatcherServlet. This class acts as front controller for String based web applications. To use this class, we are not required to modify this class. All we need is to pass initialization parameters and we can extend it’s functionality the way we want.


    eg2:
    What is means is that if the class A is written by the developer AA, and if the developer BB wants some modification on that then developer BB should be easily do that by extending class A, but not by modifying class A.
    The easy example would be the RecyclerView.Adapter class. Developers can easily extend this class and create their own custom adapter with custom behaviour without modifying the existing RecyclerView.Adapter class.
    eg3:
    A great example of this in real life is sitting in your pocket in the form of a smartphone. All such phones have app stores and these app stores let you extend the base functionality of the phone. Sure, it ships with the basics: camera operation, actual calls, text messages, etc. But via the app store, you can extend the phone's capabilities to allow you to manage your todo list, play inane video games, and even serve as a flashlight or wireless access point.
    The mechanism that allows you to do this is purely one of extension, however. It's not as though Apple, Google, and Microsoft put the OS source code up on GitHub and invite you to dive in and start building games and flashlight functionality. Rather, they make the core phone functionality closed for modification and they open it to an extension.

    3)L is for Liskov Substitution Principle


    This principle is a variation of previously discussed open closed principle. It says:
    “Derived types must be completely substitutable for their base types”
    The LSP says, basically, that any child type of a parent type should be able to stand in for that parent without things blowing up.
    It means that the classes fellow developer created by extending our class should be able to fit in application without failure. This requires the objects of your subclasses to behave in the same way as the objects of your superclass. This is mostly seen in places where we do run time type identification and then cast it to appropriate reference type.


    In other words, if you have a class, Animal, with a MakeNoise() method, then any subclass of Animal should reasonably implement MakeNoise(). Cats should meow, dogs should bark, etc. What you wouldn't do is define a MuteMouse class that throws IDontActuallyMakeNoiseException. This violates the LSP, and the argument would be that this class has no business inheriting from Animal.

    4)I is for Interface Segregation Principle



    This principle is my favorite one. It is applicable to interfaces as single responsibility principle holds to classes. ISP says:

    “Clients should not be forced to implement unnecessary methods which they will not use”

    eg1:
    Take an example. Developer Alex created an interface Reportable and added two methods generateExcel() and generatedPdf(). Now client ‘A’ wants to use this interface but he intend to use reports only in PDF format and not in excel. Will he be able to use the functionality easily?
    NO. He will have to implement both the methods, out of which one is extra burden put on him by designer of software. Either he will implement another method or leave it blank. This is not a good design.
    So what is the solution? Solution is to create two interfaces by breaking the existing one. They should be like PdfReportable and ExcelReportable. This will give the flexibility to user to use only required functionality only.


    eg2:
    To picture this in the real world, think of going down to your local corner restaurant and checking out the menu. You'll see all of the normal menu mainstays, and then something that's just called "soup of the day." Why do they do this? Because the soup changes a lot and there's no sense reprinting the menus every day. Clients that don't care about the soup needn't even be concerned, and clients that do use a different interface -- asking the server.

    5)D is for Dependency Inversion

    Most of us are already familiar with the words used in principle’s name. DI principle says:
    “Depend on abstractions, not on concretions”

    In other words. we should design our software in such a way that various modules can be separated from each other using an abstract layer to bind them together.

    The Dependency Inversion Principle (DIP) encourages you to write code that depends upon abstractions rather than upon concrete details. You can recognize this in the code you read by looking for a class or method that takes something generic like "Stream" and performs operations on it, as opposed to instantiating a specific Filestream or Stringstream or whatever. This gives the code in question a lot more flexibility -- you can swap in anything that conforms to the Stream abstraction and it will still work.
    eg1:
    To visualize this in your day to day, go down to your local store and pay for something with a credit card. The clerk doesn't examine your card and get out the "Visa Machine" after seeing that your card is a Visa. He just takes your card, whatever it is, and swipes it. Both you and the clerk depend on the credit card abstraction without worrying about specifics.

    eg2:
    The classical use of this principle of bean configuration in Spring framework.
    In spring framework, all modules are provided as separate components which can work together by simply injected dependencies in other module. This dependency is managed externally in XML files.
    These separate components are so well closed in their boundaries that we can use them in other software modules apart from spring with same ease. This has been achieved by dependency inversion and open closed principles. All modules expose only abstraction which is useful in extending the functionality or plug-in in another module



    Saturday, May 11, 2019

    All Important Design Patterns

    Factory Design Patterns

    FACTORY DESIGN PATTERN
    This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.
    Factory design pattern is used when we have a super class with multiple sub-classes and based on input,
    we need to return one of the sub-class.
    This pattern take out the responsibility of instantiation of a class from client program to t
    he factory class.
    In Factory pattern, we create object without exposing the creation logic to the client and refer to newly
    created object using a common interface.

    Implementation

    We're going to create a Shape interface and concrete classes implementing the Shape interface.
    A factory class ShapeFactory is defined as a next step.
    FactoryPatternDemo, our demo class will use ShapeFactory to get a Shapeobject.
    It will pass information (CIRCLE / RECTANGLE / SQUARE) to ShapeFactory to get the type of object it needs.
    Factory Pattern UML Diagram

    Step 1

    Create an interface.
    Shape.java
    public interface Shape {
      void draw();
    }

    Step 2

    Create concrete classes implementing the same interface.
    Rectangle.java
    public class Rectangle implements Shape {

      @Override
      public void draw() {
         System.out.println("Inside Rectangle::draw() method.");
      }
    }
    Square.java
    public class Square implements Shape {

      @Override
      public void draw() {
         System.out.println("Inside Square::draw() method.");
      }
    }
    Circle.java
    public class Circle implements Shape {

      @Override
      public void draw() {
         System.out.println("Inside Circle::draw() method.");
      }
    }

    Step 3

    Create a Factory to generate object of concrete class based on given information.
    ShapeFactory.java
    public class ShapeFactory {

      //use getShape method to get object of type shape
      public Shape getShape(String shapeType){
         if(shapeType == null){
            return null;
         }
         if(shapeType.equalsIgnoreCase("CIRCLE")){
            return new Circle();
            
         } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
            return new Rectangle();
            
         } else if(shapeType.equalsIgnoreCase("SQUARE")){
            return new Square();
         }
         
         return null;
      }
    }

    Step 4

    Use the Factory to get object of concrete class by passing an information such as type.
    FactoryPatternDemo.java
    public class FactoryPatternDemo {

      public static void main(String[] args) {
         ShapeFactory shapeFactory = new ShapeFactory();

         //get an object of Circle and call its draw method.
         Shape shape1 = shapeFactory.getShape("CIRCLE");

         //call draw method of Circle
         shape1.draw();

         //get an object of Rectangle and call its draw method.
         Shape shape2 = shapeFactory.getShape("RECTANGLE");

         //call draw method of Rectangle
         shape2.draw();

         //get an object of Square and call its draw method.
         Shape shape3 = shapeFactory.getShape("SQUARE");

         //call draw method of circle
         shape3.draw();
      }
    }

    Step 5

    Verify the output.
    Inside Circle::draw() method.
    Inside Rectangle::draw() method.
    Inside Square::draw() method.


    In OBP case we have individual adapters for Address,Contact Point,Employment Details,Party to account,Party to Party,Party Names,etc.
    All these adapters extend AbstractIntegrationAdapter (for some common methods) and implement IIntegrationAdapter(similar to shape in the above exmaple)
    IIntegrationAdapter adapter =IntegrationAdapterFactory.getInstance().fetchAdapterInstance(sessionContext,  
                                                          "party_service_core_PartyAddressApplicationService_PartyAddressDTO_updatePartyAddress");
    All are factory methods in OBP case were singleton and we also have SyncIntegrationAdapter file which stored key and value like
    public static final String party_service_core_PartyAddressApplicationService_PartyAddressDTO_updatePartyAddress =
    "com.ofss.fc.app.adapter.impl.integration.mdm.UpdatePartyAddressAdapter";

    Thus anytime we need to change the Adaper file we just needed to change in the SyncIntegrationAdaper file
    no need to change everytime in post hooks of service where we were fetching adapter instances.