Hello, Hexagonal Architecture

Hello Hexagonal Architecture


While developing a software we always craving for Architecture because we want our software adopts future changes easily.

So, Architecture stepped in for maintainability. Here maintainability mean how easily we can incorporate changes without disturbing old.

Every feature addition in a software comes with a Risk, Risk of breaking old,maintainability,rigidity,dependencies etc, There are many shades of risks
we called it Technical debt.


Technical debt has an inverse relationship of maintainability, using Architectural style we want to decrease the risk or I can say make it constant while adding new features.

We experienced that when we start writing code at that time it is easy to add features and gradually it becomes hard unless we do not use proper architecture for that software.


Hexagonal Architecture:

We will discuss Hexagonal Architecture here, in one word Hexagonal Architecture says.

Core business logic talks to other through a contract.

The core business logic means your software development logic should talk to others means Database or any JMS Queues or any Flat files or HTTP request or FTP , NOSQL etc through a contract or in Java language we can say interface.

The benefits of above type of design is whatever the input or output channels that boil down to the contract so every channel has to implement that contract/interface to talking with our software, So for our software perspective all are same as all implement the same contract so our software can deal with any types of input and output channel .

Benefits:

1, Easily incorporates any channel like Flat file,RDBMS, NoSQL, Http,Ftp,JMS etc.
2. Our software can be easily tested because it is easy to create a mock as just need to implement the contracts.

3. Adding new requirements means plugging it, or implementing the contracts.
4. Proper separation of concern.
5. Maintains IOC as Higher level and lower level talking through contract.


Sometimes we called Hexagonal architecture as Port and Adapter or Onion architecture.

As in this architecture, we have a port for each channel say for Database

The tasks we have to perform

To implement the contract to talk with our software.
As database API say JDBC is itself a contract or Hibernate is itself a framework so we need to create an adaptor GOF adapter pattern where we have to implement a strategy which converts JDBC related operation to our contract related operation.
Then plug this adaptor into our port to talk with this channel.



Outline of the design

Software Contract

package com.example.architecture.hexagonal;

public interface IPersists<T,TCOMMAND> {
   
   public void save(T t,TCOMMAND commandObject);    
   public void delete(T t,TCOMMAND commandObject);
   

}

This is the general contract for talking with our software, any output channel like File channel, RDBMS,NoSQL should implement that contract.


Here I take an example How it can talk to JPA entity which saves that data in Database.

DataBaseChannelAdapter.java
package com.example.architecture.hexagonal;

public class DataBaseChannelAdapter implements IPersists<EmployeeDomainObject,EmployeeCommand>{

   public void save(EmployeeDomainObject t, EmployeeCommand commandObject) {
     
       String underLyingJPAEntity = commandObject.getEntityClass();
       System.out.println("call save on " + underLyingJPAEntity);
     
   }

   public void delete(EmployeeDomainObject t, EmployeeCommand commandObject) {
       String underLyingJPAEntity = commandObject.getEntityClass();
       System.out.println("call delete on " + underLyingJPAEntity);
     
   }

}


As JPA Entity use some JPA related annotation so I did not include this JPA entity as part of our Domain, I use JPA framework as an Outside Channel of our software domain and DataBaseChannelAdapter takes our core domain Employee Object and takes a Command Object which tells Adapter to Which JPA entity to call and call the same.


EmployeeDomainObject

package com.example.architecture.hexagonal;

public class EmployeeDomainObject {
   
   public String name;
   public String address;
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   public String getAddress() {
      return address;
   }
   public void setAddress(String address) {
      this.address = address;
   }
   @Override
   public String toString() {
      return "EmployeeDomainObject [name=" + name + ", address=" + address
              + "]";
   }
   
   

}


Our core Domain Employee Object it does not dependent on any Framework so I can plug any framework with it through Adapter like I can easily change DatabaseAdapter to FileAdepter to save our core domain object in File.




EmployeeCommand.java

package com.example.architecture.hexagonal;

public class EmployeeCommand{
   
   public String entityClass;

   
   
   public String getEntityClass() {
      return entityClass;
   }

   public void setEntityClass(String entityClass) {
      this.entityClass = entityClass;
   }

   @Override
   public String toString() {
      return "EmployeeCommand [entityClass=" + entityClass + "]";
   }

   
   

}





This Command object is nothing but help Adapter to convert Core Domain Object to Underlying Output channel (Database or File)

EmployeeDomainDao.java

package com.example.architecture.hexagonal;

public class EmployeeDomainDao<T,TCommand>{
   
   IPersists<T,TCommand> adapter;
   
   
   public void save(T t,TCommand commandObject)
   {
      adapter.save(t, commandObject);
   }
   
   public void delete(T t,TCommand commandObject)
   {
      adapter.delete(t, commandObject);
   }

   public IPersists<T, TCommand> getAdapter() {
      return adapter;
   }

   public void setAdapter(IPersists<T, TCommand> adapter) {
      this.adapter = adapter;
   }
   
   
   

}
This is our Core Domain Persist layer here I use the adapter as Strategy based on the Adapter it will call exact output channel and persist our Domain Object.





Now Time to Test our Software design


Main.java

package com.example.architecture.hexagonal;

public class Main {
   
   public static void main(String[] args) {
      EmployeeDomainDao<EmployeeDomainObject,EmployeeCommand> dao = new EmployeeDomainDao<EmployeeDomainObject,EmployeeCommand>();
      IPersists<EmployeeDomainObject,EmployeeCommand> adapter= new DataBaseChannelAdapter();
      dao.setAdapter(adapter);
      EmployeeDomainObject emp = new EmployeeDomainObject();
      emp.setName("Shamik Mitra");
      emp.setAddress("India,Kolkata");
     
      EmployeeCommand command = new EmployeeCommand();
      command.setEntityClass("com.employeemanagement.entity.EmployeeJpaEntity");
     
      dao.save(emp, command);
      dao.delete(emp, command);
   }

}








Output:

Object StateEmployeeDomainObject [name=Shamik Mitra, address=India,Kolkata]
call save on com.employeemanagement.entity.EmployeeJpaEntity
Object StateEmployeeDomainObject [name=Shamik Mitra, address=India,Kolkata]
call delete on com.employeemanagement.entity.EmployeeJpaEntity





Hexagonal Layers :






Hexagonal architecture,port & adapter architecture,onion Arhitechture

Picture courtesy Google



Application Domain: As I said earlier it is the software where all software related business logic, validation goes on, this is the inside module every outside module talks with it through contract.

Application/Mediation Layer:  Kind of services layer it adopts the Framework layer or ut’s outside layer and make necessary changes according to domain layer contract to talks with Domain layer or in the same way return back the result from Domain to Framework layer.
It sits between Framework and Domain layer.


Framework Layer: This layer as to input/output channel or we can say the outside world and use an adaptor to adapt the data and transform it according to our  software contract.




An Interview Question on Spring Singleton

Spring Singleton


While taking interview on Spring core, Often I ask a question

What do you mean by Spring Singleton scope?

Most of the time I got an answer like Spring singleton scope manages only one object in the container.

Then after getting this answer I will ask the next question,

Please tell me what will be the output of the following program



Spring.xml file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
   
    <bean id="scopeTest" class="com.example.scope.Scope" scope="singleton">
    <property name="name" value="Shamik Mitra"/>    
    </bean>    
    <bean id="scopeTestDuplicate" class="com.example.scope.Scope" scope="singleton">
          <property name="name" value="Samir Mitra"/>    
    </bean>
</beans>


Scope.java

package com.example.scope;
public class Scope {
   private String name;

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   @Override
   public String toString() {
      return "Scope [name=" + name + "]";
   }

}

Main class

package com.example.scope;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {

   public static void main(String[] args) {
      ApplicationContext ctx = new ClassPathXmlApplicationContext(
              "configFiles/Scope.xml");

      Scope scope = (Scope) ctx.getBean("scopeTest");
      Scope scopeDuplicate = (Scope) ctx.getBean("scopeTestDuplicate");      
      System.out.println(scope==scopeDuplicate);
      System.out.println(scope  + "::"+ scopeDuplicate);
     

   }

}


Here I create two beans of Scope class and make spring scope as singleton now checking the references.


Now Interviewee got confused, and I will get three types of answer

This code will not compile throw error at runtime, as you can not define two spring beans of the same class with scope singleton in XML. (Very rare).
References check will return true, as container maintains one object so both bean definition will return the same object so memory location would be same.(Often)
They said References check will return false and Spring singleton is not worked as they have told earlier.(few)



The third answer is the correct answer, Spring singleton is not worked as Java Singleton.

If we see the output of the program we will understand that it will return two different instances, So in a  container, there may be more than one object in spite of the scope is the singleton.




Output:

Reference Check ::false
Scope [name=Shamik Mitra]::Scope [name=Samir Mitra]


So again Question is What do you mean by Spring Singleton Scope?

According to Spring documentation

When a bean is a singleton, only one shared instance of the bean will be managed, and all requests for beans with an id or ids matching that bean definition will result in that one specific bean instance being returned by the Spring container.
To put it another way, when you define a bean definition and it is scoped as a singleton, then the Spring IoC container will create exactly one instance of the object defined by that bean definition. This single instance will be stored in a cache of such singleton beans, and all subsequent requests and references for that named bean will result in the cached object being returned.


So it is clear that for a given id Spring container maintains only one shared instance in singleton cache.

In my example, I use two different ids (scopeTest, ScopeTestDuplicate) so Spring container creates two instances of the same class and bound it with respective ids and stores it in singleton cache.

You can think Spring Container manage Key-value pair where Key is the id or name of the bean and value is bean itself , so for a given key, it maintains singleton. So if we use that key as a reference of other beans the same bean will be injected to other beans.





In a one words , Spring guarantees exactly one shared bean instance for the given Id per IoC container unlike Java Singleton where Singleton hard codes the scope of an object such that one and only one instance of a particular class will ever be created per ClassLoader.

Picture taken from Spring docs

Java:Pushing runtime behaviour without Lambda

Java:Pushing runtime behaviour without Lambda



In Java8 one of the best features is Lambda Expression The Idea of Lambda expression is passing a behavior to a method.

This has been adopted from Functional programming, In Functional programming, we can pass a function  as an argument of another function or can returns a function. The function takes a function as an argument or returns a function called
Higher order function.


The benefit of this type of design is you can pass behavior and values together, so a single function can perform all types of actions on those values.

Say, I want to create the calculator so in java we have to create methods like add, subtract, multiply etc. But in the functional program paradigm, we create one method which takes another method as an argument where we define what to do.

Pseudo code
Higher order function

function void caculate (a,b,f){
    f(a,b);
}

Calling

calculate(10,20,funtion(y,z){// define and pass the method on fly

y+z;
});


In Java8 using Lambda, we can do the same if you want to know details about Lambda can consult my post  http://javaonfly.blogspot.in/2016/08/java8-lambda.html


But here we will discuss How we can achieve the same thing without Lambda. As may, many projects has not adopted java 8 due to some restrictions.

We can achieve the same by using  Interface and Anonymous class.

Step 1: Create an Interface which will provide the contract for the behavior/strategy, i.e add, subtract, multiply functionality.

So How we will achieve the same



package com.example.runtime.behaviour;

public interface IStrategy {
   
   public void operation(int operand1,int operand2);

}


Step 2: Next I will create a Calculator class where we create a method called calculate which takes two operands and the IStrategy interface as arguments.

It acts like functional programming Higher order function where we can pass method/behavior runtime.

While calling this calculate method I pass the actual implementation of IStrategy interface by using Anonymous class.

By this way, we can push behavior on runtime without Lambda Expression.


package com.example.runtime.behaviour;

public class Calculator {
   
   public void caculate(int operand1,int operand2,IStrategy runtimeBehaviour){
      runtimeBehaviour.operation(operand1, operand2);
     
   }
   
   public static void testAllOperation(){
     
      Calculator calc = new Calculator();
      calc.caculate(10, 20, new IStrategy(){

          @Override
          public void operation(int operand1, int operand2) {
              int result = operand1+operand2;
              System.out.println("ADD:: " + result);
             
          }
         
      });
     
     
      calc.caculate(10, 20, new IStrategy(){

          @Override
          public void operation(int operand1, int operand2) {
              int result = operand1*operand2;
              System.out.println("Multiply:: " + result);
             
          }
         
      });
   }
   
   public static void main(String[] args) {
      Calculator.testAllOperation();
   }

}



Look at the testAllOperationMethod here we pass two operands 10,20 and implementation of IStrategy one are for add another for multiplication.

So rather creating  4 different methods add, multiply, subtract, the division we can create one method which will support all possible operations taken on operand1 and operand2.

In Future, if any new operation like modulus will be added easily in this approach but if we use one method for one operation then you need to add a new method called modulus to Calculator class which will break Open close principle.