May 23, 2020

M1 Q03 What is an interface and what are the advantages of making use of them in Java? Why are they recommended for Spring beans?

An interface is a description of actions that an object can do, it is a way to enforce actions on an object that implements the interface.

Let's look at the code and see what does it actually mean?

This interface has actions(methods) and all of those methods need to be implemented by the classes that implement them. So if I would not implement at least one of the method, code will not compile.

Java Definition

An interface is a reference type, which contains collections of the abstract method. The class that implements the interface must implement all methods from this interface, or it needs to declare methods as abstract if the object does not know how to implement the specified method.

What does it mean?

Reference type means that we are using this as a reference. So let's look at the following test.

There is a variable defined with the type FinancialDataDao - the interface. This variable is a reference type, so I can call methods on it.

But I can also assign a different value to it.

That means that it is just a reference type.

Java Interface may contain also:

  • Constants
  • Default Methods (Java 8)
  • Static methods
  • Nested types

Advantages of using interfaces in Java

1. Allows decoupling between contract and its implementation

2. Allows declaring contract between callee and caller

Let's look at what does it mean?

This is a simple SimpleFinancialReportService that has two dependencies that will be injected into this class.

The first one is a class that implements FinancialDataDao and the second one is a class that implements FinancialReportWriter

FinancialDataDao is a caller. And the class that will implement this interface is a callee.

I can be sure that all of those methods in a class will be implemented by this class. That means that it will work correctly.

3. Increases interchangeability

Interchangeability means that I can provide any class to the field with type FinancialDataDaothat implements this interface.

For example, FinancialDataDao is implemented by DatabaseStoreFinancialDataDao and FileStoreFinancialDataDao. And I can provide both of them and I don't depend on the concrete implementation.

4. Increases testability

Testability is increased because whenever I can inject any field, any class that implements the interface. Or I can inject custom mocks like in this test I am creating the instance of the SimpleFinancialReportService and then I am providing the mocks that I have written

Advantages of using interfaces in Spring

Allows for use of JDK Dynamic Proxy

If we are using interfaces in Spring the JDK Dynamic Proxy is an option for us. Otherwise, we will need to use something that is called cglib Proxy. And both of them are having pros and cons that we will analyze in the future questions.

Allows implementation hiding

Allows to easily switch beans

Implementation hiding allows us to switch beans. It is a powerful concept.

We declare a package and this package has the public interface. However, all the other classes of the package are having package protected modifier. That means that all of those classes are not visible outside of this package.

Now you might be wondering if we have classes that are not public and we don't have any public constructor. How will we be able to use this class?

And this is when Spring is coming handy. Basically we have FinancialReportService and this class declares the dependencies as the interfaces. And it will be a Spring job to provide those dependencies based on the process called component scanning.

Also, we are using @Qualifier over here so it might be a bit hard to understand at this point and we will discuss it further.

Now, while it is useful. Let's run this example. Currently, FinancialReportService s using the DatabaseAccessObject and DatabaseWriter.

But we are using FinancialDataDao interface and we are able to easily switch beans that are implemented by this service.

We can use, for example, FileDataDao and we need to change only @Qualifier