refactor unit of work
This commit is contained in:
@@ -27,7 +27,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* {@link App} Application for managing student data.
|
||||
* {@link App} Application demonstrating unit of work pattern.
|
||||
*/
|
||||
public class App {
|
||||
/**
|
||||
@@ -37,17 +37,19 @@ public class App {
|
||||
*/
|
||||
|
||||
public static void main(String[] args) {
|
||||
var ram = new Student(1, "Ram", "Street 9, Cupertino");
|
||||
var shyam = new Student(2, "Shyam", "Z bridge, Pune");
|
||||
var gopi = new Student(3, "Gopi", "Street 10, Mumbai");
|
||||
// create some weapons
|
||||
var enchantedHammer = new Weapon(1, "enchanted hammer");
|
||||
var brokenGreatSword = new Weapon(2, "broken great sword");
|
||||
var silverTrident = new Weapon(3, "silver trident");
|
||||
|
||||
var context = new HashMap<String, List<Student>>();
|
||||
var studentDatabase = new StudentDatabase();
|
||||
var studentRepository = new StudentRepository(context, studentDatabase);
|
||||
// create repository
|
||||
var weaponRepository = new ArmsDealer(new HashMap<String, List<Weapon>>(),
|
||||
new WeaponDatabase());
|
||||
|
||||
studentRepository.registerNew(ram);
|
||||
studentRepository.registerModified(shyam);
|
||||
studentRepository.registerDeleted(gopi);
|
||||
studentRepository.commit();
|
||||
// perform operations on the weapons
|
||||
weaponRepository.registerNew(enchantedHammer);
|
||||
weaponRepository.registerModified(silverTrident);
|
||||
weaponRepository.registerDeleted(brokenGreatSword);
|
||||
weaponRepository.commit();
|
||||
}
|
||||
}
|
||||
|
@@ -30,41 +30,41 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* {@link StudentRepository} Student database repository. supports unit of work for student data.
|
||||
* {@link ArmsDealer} Weapon repository that supports unit of work for weapons.
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class StudentRepository implements IUnitOfWork<Student> {
|
||||
public class ArmsDealer implements IUnitOfWork<Weapon> {
|
||||
|
||||
private final Map<String, List<Student>> context;
|
||||
private final StudentDatabase studentDatabase;
|
||||
private final Map<String, List<Weapon>> context;
|
||||
private final WeaponDatabase weaponDatabase;
|
||||
|
||||
@Override
|
||||
public void registerNew(Student student) {
|
||||
LOGGER.info("Registering {} for insert in context.", student.getName());
|
||||
register(student, UnitActions.INSERT.getActionValue());
|
||||
public void registerNew(Weapon weapon) {
|
||||
LOGGER.info("Registering {} for insert in context.", weapon.getName());
|
||||
register(weapon, UnitActions.INSERT.getActionValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerModified(Student student) {
|
||||
LOGGER.info("Registering {} for modify in context.", student.getName());
|
||||
register(student, UnitActions.MODIFY.getActionValue());
|
||||
public void registerModified(Weapon weapon) {
|
||||
LOGGER.info("Registering {} for modify in context.", weapon.getName());
|
||||
register(weapon, UnitActions.MODIFY.getActionValue());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerDeleted(Student student) {
|
||||
LOGGER.info("Registering {} for delete in context.", student.getName());
|
||||
register(student, UnitActions.DELETE.getActionValue());
|
||||
public void registerDeleted(Weapon weapon) {
|
||||
LOGGER.info("Registering {} for delete in context.", weapon.getName());
|
||||
register(weapon, UnitActions.DELETE.getActionValue());
|
||||
}
|
||||
|
||||
private void register(Student student, String operation) {
|
||||
var studentsToOperate = context.get(operation);
|
||||
if (studentsToOperate == null) {
|
||||
studentsToOperate = new ArrayList<>();
|
||||
private void register(Weapon weapon, String operation) {
|
||||
var weaponsToOperate = context.get(operation);
|
||||
if (weaponsToOperate == null) {
|
||||
weaponsToOperate = new ArrayList<>();
|
||||
}
|
||||
studentsToOperate.add(student);
|
||||
context.put(operation, studentsToOperate);
|
||||
weaponsToOperate.add(weapon);
|
||||
context.put(operation, weaponsToOperate);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,26 +90,26 @@ public class StudentRepository implements IUnitOfWork<Student> {
|
||||
}
|
||||
|
||||
private void commitInsert() {
|
||||
var studentsToBeInserted = context.get(UnitActions.INSERT.getActionValue());
|
||||
for (var student : studentsToBeInserted) {
|
||||
LOGGER.info("Saving {} to database.", student.getName());
|
||||
studentDatabase.insert(student);
|
||||
var weaponsToBeInserted = context.get(UnitActions.INSERT.getActionValue());
|
||||
for (var weapon : weaponsToBeInserted) {
|
||||
LOGGER.info("Inserting a new weapon {} to sales rack.", weapon.getName());
|
||||
weaponDatabase.insert(weapon);
|
||||
}
|
||||
}
|
||||
|
||||
private void commitModify() {
|
||||
var modifiedStudents = context.get(UnitActions.MODIFY.getActionValue());
|
||||
for (var student : modifiedStudents) {
|
||||
LOGGER.info("Modifying {} to database.", student.getName());
|
||||
studentDatabase.modify(student);
|
||||
var modifiedWeapons = context.get(UnitActions.MODIFY.getActionValue());
|
||||
for (var weapon : modifiedWeapons) {
|
||||
LOGGER.info("Scheduling {} for modification work.", weapon.getName());
|
||||
weaponDatabase.modify(weapon);
|
||||
}
|
||||
}
|
||||
|
||||
private void commitDelete() {
|
||||
var deletedStudents = context.get(UnitActions.DELETE.getActionValue());
|
||||
for (var student : deletedStudents) {
|
||||
LOGGER.info("Deleting {} to database.", student.getName());
|
||||
studentDatabase.delete(student);
|
||||
var deletedWeapons = context.get(UnitActions.DELETE.getActionValue());
|
||||
for (var weapon : deletedWeapons) {
|
||||
LOGGER.info("Scrapping {}.", weapon.getName());
|
||||
weaponDatabase.delete(weapon);
|
||||
}
|
||||
}
|
||||
}
|
@@ -27,14 +27,12 @@ import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* {@link Student} is an entity.
|
||||
* {@link Weapon} is an entity.
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public class Student {
|
||||
public class Weapon {
|
||||
|
||||
private final Integer id;
|
||||
private final String name;
|
||||
private final String address;
|
||||
|
||||
}
|
@@ -24,19 +24,19 @@
|
||||
package com.iluwatar.unitofwork;
|
||||
|
||||
/**
|
||||
* Act as Database for student records.
|
||||
* Act as database for weapon records.
|
||||
*/
|
||||
public class StudentDatabase {
|
||||
public class WeaponDatabase {
|
||||
|
||||
public void insert(Student student) {
|
||||
public void insert(Weapon weapon) {
|
||||
//Some insert logic to DB
|
||||
}
|
||||
|
||||
public void modify(Student student) {
|
||||
public void modify(Weapon weapon) {
|
||||
//Some modify logic to DB
|
||||
}
|
||||
|
||||
public void delete(Student student) {
|
||||
public void delete(Weapon weapon) {
|
||||
//Some delete logic to DB
|
||||
}
|
||||
}
|
@@ -36,102 +36,102 @@ import java.util.Map;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* tests {@link StudentRepository}
|
||||
* tests {@link ArmsDealer}
|
||||
*/
|
||||
|
||||
class StudentRepositoryTest {
|
||||
private final Student student1 = new Student(1, "Ram", "street 9, cupertino");
|
||||
private final Student student2 = new Student(1, "Sham", "Z bridge, pune");
|
||||
class ArmsDealerTest {
|
||||
private final Weapon weapon1 = new Weapon(1, "battle ram");
|
||||
private final Weapon weapon2 = new Weapon(1, "wooden lance");
|
||||
|
||||
private final Map<String, List<Student>> context = new HashMap<>();
|
||||
private final StudentDatabase studentDatabase = mock(StudentDatabase.class);
|
||||
private final StudentRepository studentRepository = new StudentRepository(context, studentDatabase);;
|
||||
private final Map<String, List<Weapon>> context = new HashMap<>();
|
||||
private final WeaponDatabase weaponDatabase = mock(WeaponDatabase.class);
|
||||
private final ArmsDealer armsDealer = new ArmsDealer(context, weaponDatabase);;
|
||||
|
||||
@Test
|
||||
void shouldSaveNewStudentWithoutWritingToDb() {
|
||||
studentRepository.registerNew(student1);
|
||||
studentRepository.registerNew(student2);
|
||||
armsDealer.registerNew(weapon1);
|
||||
armsDealer.registerNew(weapon2);
|
||||
|
||||
assertEquals(2, context.get(UnitActions.INSERT.getActionValue()).size());
|
||||
verifyNoMoreInteractions(studentDatabase);
|
||||
verifyNoMoreInteractions(weaponDatabase);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSaveDeletedStudentWithoutWritingToDb() {
|
||||
studentRepository.registerDeleted(student1);
|
||||
studentRepository.registerDeleted(student2);
|
||||
armsDealer.registerDeleted(weapon1);
|
||||
armsDealer.registerDeleted(weapon2);
|
||||
|
||||
assertEquals(2, context.get(UnitActions.DELETE.getActionValue()).size());
|
||||
verifyNoMoreInteractions(studentDatabase);
|
||||
verifyNoMoreInteractions(weaponDatabase);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSaveModifiedStudentWithoutWritingToDb() {
|
||||
studentRepository.registerModified(student1);
|
||||
studentRepository.registerModified(student2);
|
||||
armsDealer.registerModified(weapon1);
|
||||
armsDealer.registerModified(weapon2);
|
||||
|
||||
assertEquals(2, context.get(UnitActions.MODIFY.getActionValue()).size());
|
||||
verifyNoMoreInteractions(studentDatabase);
|
||||
verifyNoMoreInteractions(weaponDatabase);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSaveAllLocalChangesToDb() {
|
||||
context.put(UnitActions.INSERT.getActionValue(), List.of(student1));
|
||||
context.put(UnitActions.MODIFY.getActionValue(), List.of(student1));
|
||||
context.put(UnitActions.DELETE.getActionValue(), List.of(student1));
|
||||
context.put(UnitActions.INSERT.getActionValue(), List.of(weapon1));
|
||||
context.put(UnitActions.MODIFY.getActionValue(), List.of(weapon1));
|
||||
context.put(UnitActions.DELETE.getActionValue(), List.of(weapon1));
|
||||
|
||||
studentRepository.commit();
|
||||
armsDealer.commit();
|
||||
|
||||
verify(studentDatabase, times(1)).insert(student1);
|
||||
verify(studentDatabase, times(1)).modify(student1);
|
||||
verify(studentDatabase, times(1)).delete(student1);
|
||||
verify(weaponDatabase, times(1)).insert(weapon1);
|
||||
verify(weaponDatabase, times(1)).modify(weapon1);
|
||||
verify(weaponDatabase, times(1)).delete(weapon1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotWriteToDbIfContextIsNull() {
|
||||
var studentRepository = new StudentRepository(null, studentDatabase);
|
||||
var weaponRepository = new ArmsDealer(null, weaponDatabase);
|
||||
|
||||
studentRepository.commit();
|
||||
weaponRepository.commit();
|
||||
|
||||
verifyNoMoreInteractions(studentDatabase);
|
||||
verifyNoMoreInteractions(weaponDatabase);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotWriteToDbIfNothingToCommit() {
|
||||
var studentRepository = new StudentRepository(new HashMap<>(), studentDatabase);
|
||||
var weaponRepository = new ArmsDealer(new HashMap<>(), weaponDatabase);
|
||||
|
||||
studentRepository.commit();
|
||||
weaponRepository.commit();
|
||||
|
||||
verifyNoMoreInteractions(studentDatabase);
|
||||
verifyNoMoreInteractions(weaponDatabase);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotInsertToDbIfNoRegisteredStudentsToBeCommitted() {
|
||||
context.put(UnitActions.MODIFY.getActionValue(), List.of(student1));
|
||||
context.put(UnitActions.DELETE.getActionValue(), List.of(student1));
|
||||
context.put(UnitActions.MODIFY.getActionValue(), List.of(weapon1));
|
||||
context.put(UnitActions.DELETE.getActionValue(), List.of(weapon1));
|
||||
|
||||
studentRepository.commit();
|
||||
armsDealer.commit();
|
||||
|
||||
verify(studentDatabase, never()).insert(student1);
|
||||
verify(weaponDatabase, never()).insert(weapon1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotModifyToDbIfNotRegisteredStudentsToBeCommitted() {
|
||||
context.put(UnitActions.INSERT.getActionValue(), List.of(student1));
|
||||
context.put(UnitActions.DELETE.getActionValue(), List.of(student1));
|
||||
context.put(UnitActions.INSERT.getActionValue(), List.of(weapon1));
|
||||
context.put(UnitActions.DELETE.getActionValue(), List.of(weapon1));
|
||||
|
||||
studentRepository.commit();
|
||||
armsDealer.commit();
|
||||
|
||||
verify(studentDatabase, never()).modify(student1);
|
||||
verify(weaponDatabase, never()).modify(weapon1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotDeleteFromDbIfNotRegisteredStudentsToBeCommitted() {
|
||||
context.put(UnitActions.INSERT.getActionValue(), List.of(student1));
|
||||
context.put(UnitActions.MODIFY.getActionValue(), List.of(student1));
|
||||
context.put(UnitActions.INSERT.getActionValue(), List.of(weapon1));
|
||||
context.put(UnitActions.MODIFY.getActionValue(), List.of(weapon1));
|
||||
|
||||
studentRepository.commit();
|
||||
armsDealer.commit();
|
||||
|
||||
verify(studentDatabase, never()).delete(student1);
|
||||
verify(weaponDatabase, never()).delete(weapon1);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user