I have two Java classes with very similar code. Basically they are almost the same excpept for a few method calls etc, i.e. replace 'ip' with 'msisdn' in the classes and they would be identical.
I'm wondering how to factor them to remove the duplication? Or maybe if there is a Design Pattern I should be using?
Here are the two classes.
public class IpQuery {
private final CommandLineInterface commandLineInterface;
private final CSVFileReader csvFileReader;
private final XMLFileReader xmlFileReader;
private final CacheQueryRequester cacheQueryRequester;
private final CacheQueryResponseParser cacheQueryResponseParser;
/**
* Invokes a cache query using the ip as a key into the session cache, displaying the result on the command line.
* <p>
* @param ipToQueryCacheFor the ip to query the PCC-A session cache for.
* @param commandLineInterface object used to display error/warning/info messages on the command line.
*/
public IpQuery(String ipToQueryCacheFor, CommandLineInterface commandLineInterface) {
this.commandLineInterface = commandLineInterface;
this.csvFileReader = new CSVFileReader(commandLineInterface);
this.xmlFileReader = new XMLFileReader(commandLineInterface);
this.cacheQueryRequester = new CacheQueryRequester();
this.cacheQueryResponseParser = new CacheQueryResponseParser();
queryCacheForSessionWithIp(ipToQueryCacheFor);
}
private void queryCacheForSessionWithIp(String ipToQueryCacheFor) {
final String configFile = commandLineInterface.getConfigFileArgValue();
if (configFile != null) {
if (configFile.endsWith(".xml")) {
final ArrayList<String> pccaPoolHosts = xmlFileReader.read(configFile);
queryPrimaryAndSecondaryPCCAForIp(ipToQueryCacheFor, pccaPoolHosts);
} else {
final ArrayList<String> pccaPoolHosts = csvFileReader.read(configFile);
queryPrimaryAndSecondaryPCCAForIp(ipToQueryCacheFor, pccaPoolHosts);
}
} else {
commandLineInterface.displayMessage(
"Warning: No CSV or XML config file entered, defaulting to querying localhost [::1].");
invokeCacheQueryForIp(ipToQueryCacheFor, "::1");
}
}
private void queryPrimaryAndSecondaryPCCAForIp(String ipToQueryCacheFor, ArrayList<String> pccaPoolHosts) {
final PCCAServerSelector pccaServerSelector = new PCCAServerSelector(pccaPoolHosts, ipToQueryCacheFor);
commandLineInterface.displayMessage(
"Info: Querying primary PCC-A [" + pccaServerSelector.getPrimaryEndpoint().getIPAddress() +"]");
invokeCacheQueryForIp(ipToQueryCacheFor, pccaServerSelector.getPrimaryEndpoint().getIPAddress());
commandLineInterface.displayMessage(
"Info: Querying secondary PCC-A [" + pccaServerSelector.getSecondaryEndpoint().getIPAddress() +"]");
invokeCacheQueryForIp(ipToQueryCacheFor, pccaServerSelector.getSecondaryEndpoint().getIPAddress());
}
private void invokeCacheQueryForIp(String ipToQueryCacheFor, String pccaHostToQuery) {
final PayLoad cacheQueryResponsePayLoad = cacheQueryRequester.queryCacheForSessionWithIp(ipToQueryCacheFor, pccaHostToQuery);
final String cacheQueryResponseAsString = cacheQueryResponseParser.parse(cacheQueryResponsePayLoad);
commandLineInterface.displayMessage(cacheQueryResponseAsString);
}
}
public class MsisdnQuery {
private final CommandLineInterface commandLineInterface;
private final CSVFileReader csvFileReader;
private final XMLFileReader xmlFileReader;
private final CacheQueryRequester cacheQueryRequester;
private final CacheQueryResponseParser cacheQueryResponseParser;
/**
* Invokes a cache query using the msisdn as a key into the session cache, displaying the result on the command line.
* <p>
* @param msisdnToQueryCacheFor the msisdn to query the PCC-A session cache for.
* @param commandLineInterface object used to display error/warning/info messages on the command line.
*/
public MsisdnQuery(String msisdnToQueryCacheFor, CommandLineInterface commandLineInterface) {
this.commandLineInterface = commandLineInterface;
this.csvFileReader = new CSVFileReader(commandLineInterface);
this.xmlFileReader = new XMLFileReader(commandLineInterface);
this.cacheQueryRequester = new CacheQueryRequester();
this.cacheQueryResponseParser = new CacheQueryResponseParser();
queryCacheForSessionWithMsisdn(msisdnToQueryCacheFor);
}
private void queryCacheForSessionWithMsisdn(String msisdnToQueryCacheFor) {
final String configFile = commandLineInterface.getConfigFileArgValue();
if (configFile != null) {
if (configFile.endsWith(".xml")) {
final ArrayList<String> pccaPoolHosts = xmlFileReader.read(configFile);
queryPrimaryAndSecondaryPCCAForMsisdn(msisdnToQueryCacheFor, pccaPoolHosts);
} else {
final ArrayList<String> pccaPoolHosts = csvFileReader.read(configFile);
queryPrimaryAndSecondaryPCCAForMsisdn(msisdnToQueryCacheFor, pccaPoolHosts);
}
} else {
commandLineInterface.displayMessage(
"Warning: No CSV or XML config file entered, defaulting to querying localhost [::1].");
invokeCacheQueryForMsisdn(msisdnToQueryCacheFor, "::1");
}
}
private void queryPrimaryAndSecondaryPCCAForMsisdn(String msisdnToQueryCacheFor, ArrayList<String> pccaPoolHosts) {
final PCCAServerSelector pccaServerSelector = new PCCAServerSelector(pccaPoolHosts, msisdnToQueryCacheFor);
commandLineInterface.displayMessage(
"Info: Querying primary PCC-A [" + pccaServerSelector.getPrimaryEndpoint().getIPAddress() +"]");
invokeCacheQueryForMsisdn(msisdnToQueryCacheFor, pccaServerSelector.getPrimaryEndpoint().getIPAddress());
commandLineInterface.displayMessage(
"Info: Querying secondary PCC-A [" + pccaServerSelector.getSecondaryEndpoint().getIPAddress() +"]");
invokeCacheQueryForMsisdn(msisdnToQueryCacheFor, pccaServerSelector.getSecondaryEndpoint().getIPAddress());
}
private void invokeCacheQueryForMsisdn(String msisdnToQueryCacheFor, String pccaHostToQuery) {
final PayLoad cacheQueryResponsePayLoad
= cacheQueryRequester.queryCacheForSessionWithMsisdn(msisdnToQueryCacheFor, pccaHostToQuery);
final String cacheQueryResponseAsString = cacheQueryResponseParser.parse(cacheQueryResponsePayLoad);
commandLineInterface.displayMessage(cacheQueryResponseAsString);
}
}
Many thanks!