Saturday, 16 October 2021

Spring Stereotype Annotations

    In this post, we can learn what are the Stereotype annotations in Spring and also difference between @Component and @Bean annotations.

In Previous one of the post we discussed all Spring Annotations,  so stereotype annotations also covered but we need to see which are those Spring annotations are stereotype annotations.

     The Stereotype annotations are special type of annotations and are used to create Spring beans automatically in the application context. The Stereotype annotations are @Component, @Controller, @Service and @Repository. @Component annotation is a parent or we can say generic stereotype. The other three annotations are derived from Component annotation.

  • @Component :- Used at class level that makes the class a component.
               @Component("employee")
       class Employee{
           private String name;
           // other fields 
       }

  • @Controller:-  Used to create Spring beans at the controller layer.
                @Controller
        @RequestMapping("employee")
        public class EmployeeController {

        }
  • @Service:-  Used to create Spring beans at the Service layer.
                 @Service
        public class EmployeeService{

        }
  • @Repository:-  Used to create Spring beans for the repositories at the DAO layer.
                @Repository
        public class EmployeeRepository{

        }

Stereotype Annotations


Difference between Component and Bean annotation:-

Friday, 9 July 2021

SOLID Design Principles with Examples

       In this post, we w'll learn the SOLID Principles with example for each principle and also to learn how to use these principles in our daily basis coding.
      
       SOLID Principles is a coding standard that all developers should follow these principles while developing any software. It was promoted by Robert C Martin and is used across the object-oriented design spectrum. When you apply SOLID principles properly in your software, it makes your code more extendable, logical, and easier to read.
      
      When the developer builds software following a bad design, the code can become inflexible and more brittle. Small changes in the software can result in bugs. For these reasons, we should follow SOLID Principles.

      It takes some time to understand, but when you follow these principles, it will improve the code quality and help you to understand the most well designed software.

Solid Design Principles in java


Let us discuss one by one in detail,

1) Single Responsibility Principle

     The Single Responsibility Principle(SRP) says that a class should have only one reason to change, which means every class should have a single responsibility or single job or single purpose.

     If single class handles multiple functionalities then in future if we do any modification then it will impact whole class not only the enhanced functionality so need to avoid this.

    The below example - Customer has the customer details like name, dateOfBirth, age, address, pinCode, phoneNumber and countryCode. As SRP principle states that class should have single responsibility but here if we do any validations on phoneNumber or address we need to do modify the complete Customer class and also it has different responsibility. So it voilates the Single Responsibility Principle.



 















The above class voilates the Single Responsibility Principle as we have address and phone detail fields are present in the same class.

    So those fields need to seperate into different classes and have to call in the customer class as follow.

 The updated customer class is below,

         If any enhancement comes in the future like do some validation on phoneNumber or address then we do modification on Phone or Address class so we can not do any modification on Customer class so this is what the SRP principle says(every class has single responsibility).


2) Open/Closed Principle

      The open/closed principle(OCP) states that a module or entity should be open for extension but closed for modification. It is one of the famous solid principles and very important in object oriented design principle.

       Bertrand Meyer says that "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”.

Open for extension means we need to design the software modules/classes in such a way that the new responsibilities or functionalities should be added easily when new requirements come.
On other hand, Closed for modification means we should not modify the class/module until we find some bugs.

Example of voilation of Open/Closed Principle:--

       In the below Payment class, there is paymentType parameter, based on this we have payment processing logic for different payment types. But in future if any enhancement comes for new payment type then we need to modify the Payment class so this voilates OCP principle.

public class Payment {
	
	public void paymentProcessing(int amount, String paymentMode) {
		
		if (paymentMode.equals("Cash")) {
			//payment process for cash
			
		} else if (paymentMode.equals("CreditCard")) {
			//payment process for creditcard
			
		} else if (paymentMode.equals("debitCard")) {
			//payment process for debitCard
			
		}
	}
}

Example to followed the Open/Closed Principle:-

In the above example voilates OCP principle, need to follow OCP Principle as follows,

public interface PaymentType {
	
	public void processPayment();
	
}

class Cash implements PaymentType {

	@Override
	public void processPayment() {
		//add cash processing logic
	}
}

class DebitCard implements PaymentType {

	@Override
	public void processPayment() {
		//add debitcard processing logic
	}
}

        In the above example, created interface PaymentType and implemented classes are Cash and DebitCard so here if in future any enhancement for new paymentType then no need to modify the existing classes/interface instead create new implemented class and implement the required payment process logic.


3) Liskov Substitution Principle(LSP)

     Liskov Substitution Principle(LSP) is a third SOLID design principle and this defined by Barbara Liskov. It extends the Open/Closed principle and enables you to replace objects of a parent class with objects of a subclass without breaking the application. This requires all subclasses to behave in the same way as the parent class.

The Principle states that, objects of a superclass shall be replaceable with objects of its subclass without breaking the application.
That requires the objects of your subclasses to behave in the same way as the objects of your superclasses.

Example:-

     In the below example, the Square is derived class extends Rectangle class, where we can set the height and width.

public class Rectangle {
    private double height;
    private double width;
    public void setHeight(double h) { height = h; }
    public void setWidht(double w) { width = w; }
    ...
}
public class Square extends Rectangle {
    public void setHeight(double h) {
        super.setHeight(h);
        super.setWidth(w);
    }
    public void setWidth(double h) {
        super.setHeight(h);
        super.setWidth(w);
    }
}

        The above code not follow's LSP because you cannot replace the Rectangle base class with its derived class Square. The Square class has extra constraints, i.e., the height and width must be the same. Therefore, substituting Rectangle with Square class may result in unexpected behavior.

     This principle is just an extension of the Open Close Principle and it means that we must make sure that new derived classes are extending the base classes without changing their behavior.


4) Interface Segregation Principle

According to Robert Martin,

     The Interface Segregation Interface Principle states that, Clients should not be forced to depend upon interfaces that they do not use.

     The main aim of this principle is to break the larger application interfaces into smaller one and each interface serves the single purpose/responsibility, it's similar to single responsiblity principle. In Clients code I mean implemented classes, if any unimplemented methods we need to override those methods also, those are really not needed so this voilates Interface Segregation Principle.

Precise application design and correct abstraction is the key behind the Interface Segregation Principle. Though it'll take more time and effort in the design phase of an application and might increase the code complexity, in the end, we get a flexible code.

Let us see below example,

The HotelOrder has an interface and there are four abstract methods, onlineOrder() , walkInCustomerOrder(), onlinePayment() and cashPayment(). 

public interface HotelOrder {
	
    public void onlineOrder();
	
    public void walkInCustomerOrder();
	
    public void onlinePayment();
	
    public void cashPayment();
}

      There are two implemented classes for HotelOrder interface i.e WalkInCustomerOrder and OnlineCustomerOrder. For WalkInCustomerOrder implementation of onlineOrder() method is not needed but HotelOrder is an interface and we need to implement all abstract methods even those methods do not use. Samething for OnlineCustomerOrder, for online customers implementation class, don't need to implement the abstract method(walkInCustomerOrder()). 

public class OnlineCustomerOrder implements HotelOrder {

	@Override
	public void onlineOrder() {
		// code logic for online order
	}

	@Override
	public void walkInCustomerOrder() {
		//this method implementation is not needed for 
		//online customers
		throw new UnsupportedOperationException();
	}

	@Override
	public void onlinePayment() {
		//write a code for online payment
		//like calling payment gateway(payment stuffs)
	}

	@Override
	public void cashPayment() {
		//this method is not needed for online order customers
		//just throw an exception
		throw new UnsupportedOperationException();
	}
	
}

public class WalkInCustomerOrder implements HotelOrder{

	@Override
	public void onlineOrder() {
		//this method implementation is not needed
		throw new UnsupportedOperationException();
	}

	@Override
	public void walkInCustomerOrder() {
		//logic for walkIn Customer order
	}

	@Override
	public void onlinePayment() {
		//this method implementation is not needed
		throw new UnsupportedOperationException();
	}

	@Override
	public void cashPayment() {
		//logic for cash payments
	}

}

     The above code violates Interface Segregation Principle, as principle says client should not override methods those they do not use.

Code to follow Interface Segregation Principle:-

Create two interfaces one with WalkIn customer and second with Online Customer, In walkin customer interface define the walkin customer related methods like walkInCustomerOrder() and cashPayment() and for online customer interface define the onlinePayment() and onlineOrder() methods so that it follows the principle and no need to override unnecessary methods in the implemented classes.

public interface OnlineCustomerHotelOrder {

	public void onlineOrder();
		
	public void onlinePayment();
}

public interface WalkInCustomerHotelOrder {
		
	public void walkInCustomerOrder();
		
	public void cashPayment();
}

Implemented classes for each order,

public class OnlineCustomerOrder implements OnlineCustomerHotelOrder {

	@Override
	public void onlineOrder() {
		// code logic for online order
	}

	@Override
	public void onlinePayment() {
		//write a code for online payment
		//like calling payment gateway(payment stuffs)
	}
}

public class WalkInCustomerOrder implements WalkInCustomerHotelOrder{

	@Override
	public void walkInCustomerOrder() {
		//logic for walkIn Customer order
	}

	@Override
	public void cashPayment() {
		//logic for cash payments
	}
}


5) Dependency Inversion Principle

The Dependency Inversion Principle is also one of Solid Principle and it concers the relationship between modules and classes.

According to Robert Martin,

The Dependency Inversion Principle says that,
  • High-level modules should not depend on low-level modules. Both should depend on abstractions.
  • Abstractions should not depend on details. Details should depend on abstractions.
Lets see below example,

The TaxCalculator is main class to calculate the different types of tax like GST, Income Tax, Professional tax and so on. In the below example, I have given two types of taxes GST and Income tax and corresponding implemented classes for each tax types.

public class TaxCalculator {
	
	public static void taxCalculator(String mode) {
		if (mode.equals("GST")) {
			GSTTaxCalculator.calculate();
		} else if (mode.equals("IncomeTax")) {
			IncomeTaxCalculator.calculate();
		}
	}
}

class GSTTaxCalculator {
	
	public static void calculate() {
		// logic to calculate GST tax
	}
}

class IncomeTaxCalculator {
	
	public static void calculate() {
		//logic to calculate IncomeTax
	}
}

In the code, in future if  we need to implement any new tax type then need to modify the main class so it voilates the Dependency Inversion Principle. The implemented class depends on main module/class so that also voilates the principle.

Need to modify the abstract class not the  main class and also implemented class/module depends on abstraction not on main module/class.

Code to follow Dependency Inversion Principle:-

Create an interface Itax and both IncomeTaxCalculator and GSTTaxCalculator implements Itax interface.

public class TaxCalculator {
		
	public static void taxCalculator(Itax itax) {
		itax.calculate();
	}
}

interface Itax {
	public void calculate();
}

class GSTTaxCalculator implements  Itax{
	
	public void calculate() {
		// logic to calculate GST tax
	}
}

class IncomeTaxCalculator implements Itax{
	
	public void calculate() {
		//logic to calculate IncomeTax
	}
}

If any question or clarification or suggestion put comment in the comment section or send an email to me anilnivargi49@gmail.com

Thank you for visting blog.

Saturday, 1 May 2021

What is Effectively Final in Java 8

     In Java 8, introduced one new concept called "effectively final" variable.

A variable or parameter whose value is never changed after it is initialized is effectively final. 

     There is no need to explicitly declare such a variable as final, although if you declare final it won't cause any issue. This effectively final variable can be used inside anonymous class or lambda expression and can not change this variable value inside anonymous class or lambda expression.

Example of effectively final:-

String str = "Acuver Consulting";
List<String> skuList = Arrays.asList("MTCCC", "MTBBB");
		
skuList.stream().forEach(s -> 
	System.out.println(str)
);

In above example, str variable is Effectively Final variable.

Example of non effective final variable,

String str = "Acuver Consulting";
str = str.concat("Pvt Ltd");
List<String> skuList = Arrays.asList("a", "b");
		
skuList.stream().forEach(s -> 
	System.out.println(str)    //Compile Time Error 
);

      When we use non effective final variable inside lambda expression or inside anonymous class, then will throw a Compile Time Error as,
"Local variable str defined in an enclosing scope must be final or effectively final"

       Difference between final and effective final variable is final variable we can explicitly declare variable with final keyword and can not reassign variable value but effective final variable no need to declare variable with final keyword and value can not be changed once it's initialized. If we change the value i.e mutable variable can not access inside the lambda expression.


Related Posts:-

Tuesday, 13 April 2021

Java Collection Framework Best Practices

       In this article we can discuss the best practices of java collection and sample examples for each usages.

1) Choose the right collection

        This is the most important step before using any collection. Depending upon functionality or problem solve to decide the right collection to use in the code implementation. There are multiple criteria to choose right collection - 

1) collection allows duplicates or not 

2) accepts null or not 

3) search based on index

4) Supports concurrency.

and also the developer should know the performance impact on each collection usages.


2) Use interface type when declaring any collection.

When you declare or create any collection, prefer to use interface type instead of specific collection class.

Example:-

List<String> listOfItems = new ArrayList<>();

instead of,

ArrayList<String> listOfItems = new ArrayList<>();

Using interface type is more flexible and convenient because we can change concreate implementation as needed.

For example,  List<String> listOfItems = new LinkedList<>();


3) Method return type should be interface instead of collection class.

       Best practice to return type of method should be interface instead of collection class. It is more flexible because if any changes done inside the method should not impact on the caller.

 public List<String> getAllItems() {
      
      List<String> listOfItems = new ArrayList<>();
      
      //in future if we change arrayList to linkedList it doesn't impact on caller
      // get all items - fetch items from database

      return listOfItems;
 }

4) Use generic type and diamond operator

        Use generic type when declare any collection otherwise chances of throwing ClassCastException at run time.

Example : - 

List listOfItems = new ArrayList<>();

listOfItems.add("item");

listOfItems.add(1);

so avoid using above declaration, apply generics,

List<String> listOfItems = new ArrayList<>();

listOfItems.add("company");

listOfItems.add(12);     //compile time error

 Use diamond operator(<>),

This operator <> is called the diamond operator. Without diamond operator we have to write declaration twice so using this operator no need to write declaration twice as follows,

List<String> listOfItems = new ArrayList<String>();

With <> operator,

List<String> listOfItems = new ArrayList<>();


5) Prefer to use Collection isEmpty() or CollectionUtils.isEmpty()  methods instead of size() method

Checking the emptiness of collection, avoid using size method like,

if  (listOfItems.size > 0)  {
   //write logic if list is not empty
}

Prefer to use collection or collection util methods,

if  (!listOfItems.isEmpty())  {
    //write logic if list is not empty
}

or use collection util(apache) method,

if (CollectionUtils.isNotEmpty(listOfItems)) {
      //write logic if list is not empty
}


6) Specify initial capacity of a collection if possible

        When we process a batch of records then prefer to specify the collection initial capacity as a batch size so it avoids every time to resize the collection capacity when it exceeds the default capacity.

List<String> listOfItems = new ArrayList<>(500);

This creates an array list of 500 elements initially.

7)  Return an empty array or collection instead of a null value for methods that return an array or collection

       If the method is collection valued then return empty collection instead of returning null because the client side no need to handle null check it's kind of extra
code to write in the client side. 

//Avoid this
public List<String> getAllPreSaleItems(String itemType) {
		
	List<String> preSaleItems = null;
	if (itemType.equalsIgnoreCase("preSale")) {
		//preSaleItems = fetch all presale items from database
	}
	return preSaleItems;
}

Best practice to return empty list as, 

//best practice to return empty list
private List<String> getAllPreSaleItems(String itemType) {
		
	List<String> preSaleItems = null;
	if (itemType.equalsIgnoreCase("preSale")) {
		//preSaleItems = fetch all presale items from database
	}
	if (preSaleItems == null) {
		return Collections.EMPTY_LIST;
	}
	return preSaleItems;
}

8) Do not use the classic for loop

Classic for loop,

List<String> listOfItems = Arrays.asList("a", "b", "c");
for (int i=0; i<listOfItems.size(); i++) {
   System.out.println(listOfItems(i));
}

Better to use for-each loop,

List<String> listOfItems = Arrays.asList("a", "b", "c");
for (String item : listOfItems) {
   System.out.println(item);
}

The advantage of the for-each loop is that it eliminates the possibility of bugs and makes the code more readable. It traverses each element one by one. 

9) Prefer to use forEach() with Lambda expressions(Java 8 onwards)

       In forEach() method use java 8 lambda expression,  so that the code even more compact, more flexible and more powerful.

Example:-

List<String> skuList = Arrays.asList("MTCCC", "MTAAA", "PT1111");
 
skuList.forEach(sku -> System.out.println(sku));


10) Prefer concurrent collections over synchronized wrappers

          When we develop any multi-threaded applications,  consider using concurrent collections in the java.util.concurrent package instead of using the synchronized 
collections generated by the Collections.synchronizedXXX() methods.
         It’s because the concurrent collections are designed to provide maximum performance in concurrent applications,  by implementing different synchronization mechanisms like copy-on-write, compare-and-swap and special locks. 
 
Example of concurrent package classes are ConcurrentHashMap, CopyOnWriteArrayList, ConcurrentSkipListMap and PriorityBlockingQueue.


Related Posts:-