Kunal Malhotra
Kunal Malhotra

Reputation: 51

Not able to refactor the code in methods?

I have a scenario where i have four methods containing all the same code except one or two line in try block. Can any suggest how to refactor it?

I tried Enum and switch,but not able to find the correct implementation. The problem is all methods have different return type.

 public static void insertDocument(Test database, Test2 collectionName, Document docToInsert) {
        int count = 0;
        int maxTries = getMongoQueryRetries();
        while (count < maxTries + 1) {
            try {
                addUniqueId(docToInsert);
                database.getCollection(collectionName).insertOne(docToInsert);
                return;
            } catch (MongoTimeoutException | MongoSocketReadTimeoutException | MongoSocketClosedException | MongoSocketReadException | MongoNotPrimaryException e) {
                if (++count == maxTries) {
                    LOG.error(e.getMessage());
                    throw e;
                }
            } catch (MongoSocketException | MongoServerException e) {
                if (++count == maxTries) {
                    LOG.error(e.getMessage());
                    throw e;
                }
            } catch (Throwable e) {
                LOG.error(e.getMessage());
                throw e;
            }

        }

    }


    public static FindIterable<Document> findDocument(MongoDatabase database, String collectionName, Document docToFind) {
        int count = 0;
        int maxTries = getMongoQueryRetries();
        FindIterable<Document> document = null;
        while (count < maxTries + 1) {
            try {
                return database.getCollection(collectionName).find(docToFind);
            } catch (MongoTimeoutException | MongoSocketReadTimeoutException | MongoSocketClosedException | MongoSocketReadException | MongoNotPrimaryException e) {
                if (++count == maxTries) {
                    LOG.error(e.getMessage());
                    throw e;
                }
            } catch (MongoSocketException | MongoServerException e) {
                if (++count == maxTries) {
                    LOG.error(e.getMessage());
                    throw e;
                }
            } catch (Throwable e) {
                LOG.error(e.getMessage());
                throw e;
            }
        }
        return document;
    }


    public static DeleteResult deleteDocument(MongoDatabase database, String collectionName, Document docToDelete) {
        int count = 0;
        int maxTries = getMongoQueryRetries();
        DeleteResult deleteResult = null;
        while (count < maxTries + 1) {
            try {
                deleteResult = database.getCollection(collectionName).deleteOne(docToDelete);
                return deleteResult;
            } catch (MongoTimeoutException | MongoSocketReadTimeoutException | MongoSocketClosedException | MongoSocketReadException | MongoNotPrimaryException e) {
                if (++count == maxTries) {
                    LOG.error(e.getMessage());
                    throw e;
                }
            } catch (MongoSocketException | MongoServerException e) {
                if (++count == maxTries) {
                    LOG.error(e.getMessage());
                    throw e;
                }
            } catch (Throwable e) {
                LOG.error(e.getMessage());
                throw e;
            }

        }

        return deleteResult;
    }


    public static void findAndReplaceDocument(MongoDatabase database, String collectionName, Document docToBeReplaced, Document newDocument) {
        int count = 0;
        int maxTries = getMongoQueryRetries();
        while (count < maxTries + 1) {
            try {
                database.getCollection(collectionName).findOneAndReplace(docToBeReplaced, newDocument);
                return;
            } catch (MongoTimeoutException | MongoSocketReadTimeoutException | MongoSocketClosedException | MongoSocketReadException | MongoNotPrimaryException e) {
                if (++count == maxTries) {
                    LOG.error(e.getMessage());
                    throw e;
                }
            } catch (MongoSocketException | MongoServerException e) {
                if (++count == maxTries) {
                    LOG.error(e.getMessage());
                    throw e;
                }
            } catch (Throwable e) {
                LOG.error(e.getMessage());
                throw e;
            }

        }
    }

Excepted: To have all the logic in one place

Upvotes: 0

Views: 107

Answers (1)

GhostCat
GhostCat

Reputation: 140417

I think that could be done via a Callable, like:

public static <T> T processDbAction(Callable<T> dbAction) {
    int count = 0;
    int maxTries = getMongoQueryRetries();
    while (count < maxTries + 1) {
        try {
           return dbAction.call();
        } catch (MongoTimeoutException | MongoSocketReadTimeoutException | MongoSocketClosedException | MongoSocketReadException | MongoNotPrimaryException e) {
            if (++count == maxTries) {
                LOG.error(e.getMessage());
                throw e;
            }
        } catch (MongoSocketException | MongoServerException e) {
            if (++count == maxTries) {
                LOG.error(e.getMessage());
                throw e;
            }
        } catch (Throwable e) {
            LOG.error(e.getMessage());
            throw e;
        }
    }
}

In other words: you start with such a helper method that puts all the common "framework" around your call. And then you have different implementations of the Callable interface that can focus on their core business, without worrying about retries or exception handling/logging.

Like:

public FindAction implements Callable<Document> {
   private final MongoDatabase database;
   private final collectionName;
   private final Document docToFind;
... 

 @Override
 public Document call() throws Exception {
   return database.getCollection(collectionName).find(docToFind);
 }

Upvotes: 1

Related Questions