Batch Processing : Design check with SRP and OCP prinicple I have to create a batch process which reads data from DB , process it and saves it in db . The batch data is fetched organization wise ( each organization has set of data to be processed) at once.We need to process only specific set of data i.e organization related and save it into db. Hence i have designed below classes . Does this design breaks SRP and OCP?

Should the process method in DepositProcess have the code to iterate the batch data ?

Batch Processor Interface

package com.ibank.batch;

public interface BatchProcessor {

    public void process();

}


Deposit Processort class

package com.ibank.batch;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.ibank.batch.svc.DepositBatchProcessorSvc;

public class DepositProcessor implements BatchProcessor {

    @Override
    public void process() {
        DepositBatchProcessorSvc svc = new DepositBatchProcessorSvc();
        HashMap&lt;String, List&lt;String&gt;&gt; batchData = svc.fetchBatchData();
        Set&lt;String&gt; key = batchData.keySet();
        Iterator&lt;String&gt; keyItr = key.iterator();
        while (keyItr.hasNext()) {
            String organizationId = (String) keyItr.next();
            List&lt;String&gt; claimsList = batchData.get(organizationId);
            svc.saveBatchData(claimsList);
        }
    }

}


Service interface and implementation class

package com.ibank.batch.svc;

import java.util.List;

public interface BatchProcessorSvc {

    public Object fetchBatchData();


    public &lt;T&gt;  void  saveBatchData(List&lt;T&gt; data);



}


package com.ibank.batch.svc;

import java.util.HashMap;
import java.util.List;

public class DepositBatchProcessorSvc implements BatchProcessorSvc {

    @Override
    public HashMap&lt;String, List&lt;String&gt;&gt; fetchBatchData() {
        return null;

    }

    @Override
    public &lt;String&gt; void saveBatchData(List&lt;String&gt; claimList) {

    }

}


DAO interface and implementation  

package com.ibank.batch.dao;

import java.util.List;

public interface BatchProcessorDao {

    public Object fetchBatchData();

    public &lt;T&gt;  void  saveBatchData(List&lt;T&gt; data);



}


package com.ibank.batch.dao;

import java.util.HashMap;
import java.util.List;

public class DepositBatchProcessorDao implements BatchProcessorDao {

    @Override
    public HashMap&lt;String, List&lt;String&gt;&gt; fetchBatchData() {
        return null;
    }

    @Override
    public &lt;String&gt; void saveBatchData(List&lt;String&gt; claimList) {

    }



}
Quick question, have you tried testing your code? Trying doing so, and you will find the leaks in your code.


DepositProcessor has a high dependency on DepositBatchProcessorSvc, why not to inject it and make the code flexible (easier to test and change).

public class DepositProcessor{
   private final DepositBatchProcessorSvc service;
   DepositProcessor(DepositBatchProcessorSvc service){
    this.service = service;
  }
}

BatchProcessorSvc could be totally generified,

/*K type of the object's promary key, and T is the object type*/
public interface BatchProcessorDao&lt;K,T&gt; {
  @Override
  Map&lt;K, List&lt;T&gt;&gt; fetchBatchData();
}

Always try to return interfaces and not implementations, ex:

HashMap&lt;String, List&lt;String&gt;&gt; fetchBatchData()


could be refactored to

Map&lt;String, List&lt;String&gt;&gt; fetchBatchData()

Save should never be fire and forget, I know a lot of db clients do it, but it is really bad, I need to know if things were saved successfully, wishful programming is bad, you could return the objects after saving them

List&lt;T&gt; saveBatchData(List&lt;T&gt; data);