1. Overview
2. Hexagonal Architecture
In terms of programming (implementation), a port is an interface while an adapter is the concrete implementation of a given port.
3. Hexagonal Architecture example in Java
3.1 Define Domain layer
public class Student {
private int studentId;
private String name;
private int age;
}
public interface StudentService {
public List<Student> findAll();
public void save(Student student);
}
Let's implement StudentService interface now.
@Service
public class StudentServiceImpl implements StudentService {
private StudentDBPort studentDBPort;
@Autowired
public StudentServiceImpl(StudentDBPort studentDBPort) {
super();
this.studentDBPort = studentDBPort;
}
@Override public List<Student> findAll() {
return studentDBPort.findAll();
}
@Override public void save(Student student) {
studentDBPort.save(student);
}
}
3.2 Declare Ports
public interface StudentDBPort {
public List<Student> findAll();
public void save(Student student);
}
3.3 Implement Adapters
public class StudentControllerAdapter implements StudentRESTPort {
@Autowired
private StudentService studentService;
@RequestMapping(method = RequestMethod.POST, value = "/register")
public Student registerStudent(@RequestBody Student student) {
studentService.save(student);
return student;
}
@RequestMapping(method = RequestMethod.GET, value = "/viewAll")
public List<Student> getAllStudents() {
return studentService.findAll();
}
}
Then, we'll create the StudentServiceDBAdapter class that implements the StudentDBPort interface. So, it'll behave as an adapter to persist data in the database:public class StudentServiceDBAdapter implements StudentDBPort {
private EntityManager entityManager;
@Override
public List<Student> findAll() {
Session currentSession = entityManager.unwrap(Session.class);
Query<Student> theQuery = currentSession.createQuery("from Student", Student.class);
List<Student> students = theQuery.getResultList();
return students;
}
@Override
public void save(Student student) {
Session currentSession = entityManager.unwrap(Session.class);
currentSession.saveOrUpdate(student);
}
}
That's it, we've successfully separated our App into the inside and outside components.4. Benefits
- Independence : The core layer is independent of outer layers
- Testability : Each dependent (outer) component could be easily replaced with a stub implementation so that any component can be tested with ease
- Flexibility : Any number of ports can be added easily to serve multiple functionalities\channels
No comments:
Post a Comment