Observability Done Right: Best Practices and Anti-Patterns for Effective System Monitoring

Image
  WHAT Observability is a concept that refers to the ability to gain insights into the behavior and performance of complex systems. In the context of software engineering, observability involves the collection, analysis, and visualization of data from software applications, infrastructure, and other components of a system. In the animal kingdom, observability plays a critical role in survival, allowing animals to monitor their surroundings, detect threats, and find food. Dolphins use echolocation to observe their surroundings. They emit high-frequency sounds that bounce off objects, allowing them to create a 3D map of their environment. Thanks for reading Knowledge Cafe! Subscribe for free to receive new posts and support my work. Subscribed WHY In today's era, architectures are becoming increasingly large, complex, and fast-paced due to the faster development and deployment of software by distributed teams with the help of DevOps, continuous delivery, and agile development methodo...

Java Double Brace Initialization




Double brace initialization is a combination of two separate process in java. There are two { braces involved in it. If you see two consecutive curly braces { in java code, it is an usage of double brace initialization.

JavaLanguage doesn't have a convenient literal syntax for collections (lists, maps, sets, etc.). This makes creating constant collections or passing collections to functions quite laborious. Every time you have to

  1. Declare a variable for a temporary collection

  2. Create a new empty collection and store a reference to it in the variable

  3. Put things into the collection

  4. Pass the collection to the method

Below Sample code explain conventional style.

package doublebracecollection;
import java.util.HashSet;
import java.util.Set;

public class NormalInitialization {

	    public static void main(String[] args) {
	        Set<String> params = new HashSet<String>();
	        params.add("one");
	        params.add("two");
	        params.add("three");
	        params.add("four");
	        // ... and so on; Now pass above collection as parameter to method or some other ways
	        myPrintMethod(params);
	    }

	    private static void myPrintMethod(Set<String> mySet) {
	        System.out.println(mySet);
	    }
}

Lets see how to use Double brace initialization, we will implement same functionality as above so easy to compare code readability,

package doublebracecollection;

import java.util.HashSet;
import java.util.Set;

public class DoubleBraceOne {
    public static void main(String[] args) {
        Set<String> params = new HashSet<String>() {
            {
            	add("one");
    	        add("two");
    	        add("three");
    	        add("four");
            }
        };
        // ... and so on; Now pass above collection as parameter to method or
        // some other ways
        myPrintMethod(params);
    }

    private static void myPrintMethod(Set<String> mySet) {
    	System.out.println(mySet);
    }
}

First brace is creation of ananonymous inner class. Without considering the second brace if you see the first brace alone then its nothing new for us. We have created many anonymous inner classes in such a way.

Second brace is an initialization block. That too you have seen in it a class for initialization. You may have used a static initialization block. When you use the initialization block for an anonymous inner class it becomes java double brace initialization. The inner class created will have a reference to the enclosing outer class. That reference can be used using the ‘this’ pointer.

We can even make it  even simpler as below,

package doublebracecollection;

import java.util.HashSet;
import java.util.Set;

public class DoubleBraceTwo {
	 public static void main(String[] args) {

		 myPrintMethod(new HashSet<String>() {
	            {
	                add("one");
	                add("two");
	                add("three");
	                add("four");
	            }
	        });
	    }

	 private static void myPrintMethod(Set<String> mySet) {
	    	System.out.println(mySet);
	    }
}

 

Important points

  • As classes initialized this way are basically inner classes. So we can create for non final classes.

  • Such classes should not be used where equals() method is not explicitly modified to use them because mostly equals() method checks for class equality also.

  • You should always keep in mind that initializers are run before constructors (but not before super class constructors).

  • The instance of the anonymous class that you have created contain a synthetic reference to the enclosing object. If you serialize the collection you will also serialize everything in the outer class.

  • There will be performance hit for this process, I will publish one more article for performance comparison of traditional method vs double brace initialization. 

Popular posts from this blog

Chain of responsibility using Spring @Autowired List

Iterate Through a HashMap

Under the Hood: Understanding the Gossip Protocol in Apache Cassandra