diff --git a/caching/src/main/java/com/iluwatar/caching/App.java b/caching/src/main/java/com/iluwatar/caching/App.java
index 14f16f365..0882fc165 100644
--- a/caching/src/main/java/com/iluwatar/caching/App.java
+++ b/caching/src/main/java/com/iluwatar/caching/App.java
@@ -1,26 +1,3 @@
-/*
- * The MIT License
- * Copyright © 2014-2021 Ilkka Seppälä
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
package com.iluwatar.caching;
import com.iluwatar.caching.database.DbManager;
@@ -28,33 +5,42 @@ import com.iluwatar.caching.database.DbManagerFactory;
import lombok.extern.slf4j.Slf4j;
/**
- * The Caching pattern describes how to avoid expensive re-acquisition of resources by not releasing
- * the resources immediately after their use. The resources retain their identity, are kept in some
- * fast-access storage, and are re-used to avoid having to acquire them again. There are four main
- * caching strategies/techniques in this pattern; each with their own pros and cons. They are;
- * write-through
which writes data to the cache and DB in a single transaction,
- * write-around
which writes data immediately into the DB instead of the cache,
- * write-behind
which writes data into the cache initially whilst the data is only
- * written into the DB when the cache is full, and cache-aside
which pushes the
- * responsibility of keeping the data synchronized in both data sources to the application itself.
- * The read-through
strategy is also included in the mentioned four strategies --
- * returns data from the cache to the caller if it exists else queries from DB and
- * stores it into the cache for future use. These strategies determine when the data in the cache
- * should be written back to the backing store (i.e. Database) and help keep both data sources
- * synchronized/up-to-date. This pattern can improve performance and also helps to maintain
- * consistency between data held in the cache and the data in the underlying data store.
+ * The Caching pattern describes how to avoid expensive re-acquisition of
+ * resources by not releasing the resources immediately after their use.
+ * The resources retain their identity, are kept in some fast-access storage,
+ * and are re-used to avoid having to acquire them again. There are four main
+ * caching strategies/techniques in this pattern; each with their own pros and
+ * cons. They are write-through
which writes data to the cache and
+ * DB in a single transaction, write-around
which writes data
+ * immediately into the DB instead of the cache, write-behind
+ * which writes data into the cache initially whilst the data is only
+ * written into the DB when the cache is full, and cache-aside
+ * which pushes the responsibility of keeping the data synchronized in both
+ * data sources to the application itself. The read-through
+ * strategy is also included in the mentioned four strategies --
+ * returns data from the cache to the caller if it exists else
+ * queries from DB and stores it into the cache for future use. These strategies
+ * determine when the data in the cache should be written back to the backing
+ * store (i.e. Database) and help keep both data sources
+ * synchronized/up-to-date. This pattern can improve performance and also helps
+ * to maintainconsistency between data held in the cache and the data in
+ * the underlying data store.
*
- *
In this example, the user account ({@link UserAccount}) entity is used as the underlying - * application data. The cache itself is implemented as an internal (Java) data structure. It adopts - * a Least-Recently-Used (LRU) strategy for evicting data from itself when its full. The four - * strategies are individually tested. The testing of the cache is restricted towards saving and - * querying of user accounts from the underlying data store ( {@link DbManager}). The main class ( - * {@link App} is not aware of the underlying mechanics of the application (i.e. save and query) and - * whether the data is coming from the cache or the DB (i.e. separation of concern). The AppManager - * ({@link AppManager}) handles the transaction of data to-and-from the underlying data store - * (depending on the preferred caching policy/strategy). + *
In this example, the user account ({@link UserAccount}) entity is used + * as the underlying application data. The cache itself is implemented as an + * internal (Java) data structure. It adopts a Least-Recently-Used (LRU) + * strategy for evicting data from itself when its full. The four + * strategies are individually tested. The testing of the cache is restricted + * towards saving and querying of user accounts from the + * underlying data store( {@link DbManager}). The main class ( {@link App} + * is not aware of the underlying mechanics of the application + * (i.e. save and query) and whether the data is coming from the cache or the + * DB (i.e. separation of concern). The AppManager ({@link AppManager}) handles + * the transaction of data to-and-from the underlying data store (depending on + * the preferred caching policy/strategy). *
- * {@literal App --> AppManager --> CacheStore/LRUCache/CachingPolicy --> DBManager} + * {@literal App --> AppManager --> CacheStore/LRUCache/CachingPolicy --> + * DBManager} *
* *
@@ -68,10 +54,20 @@ import lombok.extern.slf4j.Slf4j;
*/
@Slf4j
public class App {
+ /**
+ * Constant parameter name to use mongoDB.
+ */
private static final String USE_MONGO_DB = "--mongo";
- private AppManager appManager;
+ /**
+ * Application manager.
+ */
+ private final AppManager appManager;
- public App(boolean isMongo) {
+ /**
+ * Constructor of current App.
+ * @param isMongo boolean
+ */
+ public App(final boolean isMongo) {
DbManager dbManager = DbManagerFactory.initDb(isMongo);
appManager = new AppManager(dbManager);
appManager.initDb();
@@ -82,20 +78,20 @@ public class App {
*
* @param args command line args
*/
- public static void main(String[] args) {
+ public static void main(final String[] args) {
// VirtualDB (instead of MongoDB) was used in running the JUnit tests
// and the App class to avoid Maven compilation errors. Set flag to
// true to run the tests with MongoDB (provided that MongoDB is
// installed and socket connection is open).
App app = new App(isDbMongo(args));
app.useReadAndWriteThroughStrategy();
- System.out.println("=====================================================");
+ System.out.println("==============================================");
app.useReadThroughAndWriteAroundStrategy();
- System.out.println("=====================================================");
+ System.out.println("==============================================");
app.useReadThroughAndWriteBehindStrategy();
- System.out.println("=====================================================");
+ System.out.println("==============================================");
app.useCacheAsideStategy();
- System.out.println("=====================================================");
+ System.out.println("==============================================");
}
/**
@@ -103,7 +99,7 @@ public class App {
* @param args input params
* @return true if there is "--mongo" parameter in arguments
*/
- private static boolean isDbMongo(String[] args) {
+ private static boolean isDbMongo(final String[] args) {
for (String arg : args) {
if (arg.equals(USE_MONGO_DB)) {
return true;
@@ -156,9 +152,15 @@ public class App {
LOGGER.info("# CachingPolicy.BEHIND");
appManager.initCachingPolicy(CachingPolicy.BEHIND);
- var userAccount3 = new UserAccount("003", "Adam", "He likes food.");
- var userAccount4 = new UserAccount("004", "Rita", "She hates cats.");
- var userAccount5 = new UserAccount("005", "Isaac", "He is allergic to mustard.");
+ var userAccount3 = new UserAccount("003",
+ "Adam",
+ "He likes food.");
+ var userAccount4 = new UserAccount("004",
+ "Rita",
+ "She hates cats.");
+ var userAccount5 = new UserAccount("005",
+ "Isaac",
+ "He is allergic to mustard.");
appManager.save(userAccount3);
appManager.save(userAccount4);
@@ -166,7 +168,9 @@ public class App {
LOGGER.info(appManager.printCacheContent());
appManager.find("003");
LOGGER.info(appManager.printCacheContent());
- UserAccount userAccount6 = new UserAccount("006", "Yasha", "She is an only child.");
+ UserAccount userAccount6 = new UserAccount("006",
+ "Yasha",
+ "She is an only child.");
appManager.save(userAccount6);
LOGGER.info(appManager.printCacheContent());
appManager.find("004");
@@ -181,9 +185,15 @@ public class App {
appManager.initCachingPolicy(CachingPolicy.ASIDE);
LOGGER.info(appManager.printCacheContent());
- var userAccount3 = new UserAccount("003", "Adam", "He likes food.");
- var userAccount4 = new UserAccount("004", "Rita", "She hates cats.");
- var userAccount5 = new UserAccount("005", "Isaac", "He is allergic to mustard.");
+ var userAccount3 = new UserAccount("003",
+ "Adam",
+ "He likes food.");
+ var userAccount4 = new UserAccount("004",
+ "Rita",
+ "She hates cats.");
+ var userAccount5 = new UserAccount("005",
+ "Isaac",
+ "He is allergic to mustard.");
appManager.save(userAccount3);
appManager.save(userAccount4);
appManager.save(userAccount5);
diff --git a/caching/src/main/java/com/iluwatar/caching/AppManager.java b/caching/src/main/java/com/iluwatar/caching/AppManager.java
index 880791034..cdf26b194 100644
--- a/caching/src/main/java/com/iluwatar/caching/AppManager.java
+++ b/caching/src/main/java/com/iluwatar/caching/AppManager.java
@@ -29,28 +29,41 @@ import com.iluwatar.caching.database.DbManager;
import lombok.extern.slf4j.Slf4j;
/**
- * AppManager helps to bridge the gap in communication between the main class and the application's
- * back-end. DB connection is initialized through this class. The chosen caching strategy/policy is
- * also initialized here. Before the cache can be used, the size of the cache has to be set.
- * Depending on the chosen caching policy, AppManager will call the appropriate function in the
- * CacheStore class.
+ * AppManager helps to bridge the gap in communication between the main class
+ * and the application's back-end. DB connection is initialized through this
+ * class. The chosen caching strategy/policy is also initialized here.
+ * Before the cache can be used, the size of the cache has to be set.
+ * Depending on the chosen caching policy, AppManager will call the
+ * appropriate function in the CacheStore class.
*/
@Slf4j
public class AppManager {
-
+ /**
+ * Caching Policy.
+ */
private static CachingPolicy cachingPolicy;
+ /**
+ * Database Manager.
+ */
private final DbManager dbManager;
+ /**
+ * Cache Store.
+ */
private final CacheStore cacheStore;
- public AppManager(DbManager dbManager) {
- this.dbManager = dbManager;
- this.cacheStore = new CacheStore(dbManager);
+ /**
+ * Constructor.
+ * @param newDbManager database manager
+ */
+ public AppManager(final DbManager newDbManager) {
+ this.dbManager = newDbManager;
+ this.cacheStore = new CacheStore(newDbManager);
}
/**
- * Developer/Tester is able to choose whether the application should use MongoDB as its underlying
- * data storage or a simple Java data structure to (temporarily) store the data/objects during
- * runtime.
+ * Developer/Tester is able to choose whether the application should use
+ * MongoDB as its underlying data storage or a simple Java data structure
+ * to (temporarily) store the data/objects during runtime.
*/
public void initDb() {
dbManager.connect();
@@ -58,8 +71,9 @@ public class AppManager {
/**
* Initialize caching policy.
+ * @param policy is a {@link CachingPolicy}
*/
- public void initCachingPolicy(CachingPolicy policy) {
+ public void initCachingPolicy(final CachingPolicy policy) {
cachingPolicy = policy;
if (cachingPolicy == CachingPolicy.BEHIND) {
Runtime.getRuntime().addShutdownHook(new Thread(cacheStore::flushCache));
@@ -69,10 +83,13 @@ public class AppManager {
/**
* Find user account.
+ * @param userId String
+ * @return {@link UserAccount}
*/
- public UserAccount find(String userId) {
+ public UserAccount find(final String userId) {
LOGGER.info("Trying to find {} in cache", userId);
- if (cachingPolicy == CachingPolicy.THROUGH || cachingPolicy == CachingPolicy.AROUND) {
+ if (cachingPolicy == CachingPolicy.THROUGH
+ || cachingPolicy == CachingPolicy.AROUND) {
return cacheStore.readThrough(userId);
} else if (cachingPolicy == CachingPolicy.BEHIND) {
return cacheStore.readThroughWithWriteBackPolicy(userId);
@@ -84,8 +101,9 @@ public class AppManager {
/**
* Save user account.
+ * @param userAccount {@link UserAccount}
*/
- public void save(UserAccount userAccount) {
+ public void save(final UserAccount userAccount) {
LOGGER.info("Save record!");
if (cachingPolicy == CachingPolicy.THROUGH) {
cacheStore.writeThrough(userAccount);
@@ -98,25 +116,33 @@ public class AppManager {
}
}
+ /**
+ * Returns String.
+ * @return String
+ */
public String printCacheContent() {
return cacheStore.print();
}
/**
* Cache-Aside save user account helper.
+ * @param userAccount {@link UserAccount}
*/
- private void saveAside(UserAccount userAccount) {
+ private void saveAside(final UserAccount userAccount) {
dbManager.updateDb(userAccount);
cacheStore.invalidate(userAccount.getUserId());
}
/**
* Cache-Aside find user account helper.
+ * @param userId String
+ * @return {@link UserAccount}
*/
- private UserAccount findAside(String userId) {
+ private UserAccount findAside(final String userId) {
return Optional.ofNullable(cacheStore.get(userId))
.or(() -> {
- Optional DBManager handles the communication with the underlying data store i.e. Database. It contains
- * the implemented methods for querying, inserting, and updating data. MongoDB was used as the
- * database for the application. DBManager handles the communication with the underlying data store i.e.
+ * Database. It contains the implemented methods for querying, inserting,
+ * and updating data. MongoDB was used as the database for the application.