1
- /*
2
- * The MIT License
3
- * Copyright © 2014-2021 Ilkka Seppälä
4
- *
5
- * Permission is hereby granted, free of charge, to any person obtaining a copy
6
- * of this software and associated documentation files (the "Software"), to deal
7
- * in the Software without restriction, including without limitation the rights
8
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- * copies of the Software, and to permit persons to whom the Software is
10
- * furnished to do so, subject to the following conditions:
11
- *
12
- * The above copyright notice and this permission notice shall be included in
13
- * all copies or substantial portions of the Software.
14
- *
15
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- * THE SOFTWARE.
22
- */
23
-
24
1
package com .iluwatar .caching ;
25
2
26
3
import com .iluwatar .caching .database .DbManager ;
27
4
import com .iluwatar .caching .database .DbManagerFactory ;
28
5
import lombok .extern .slf4j .Slf4j ;
29
6
30
7
/**
31
- * The Caching pattern describes how to avoid expensive re-acquisition of resources by not releasing
32
- * the resources immediately after their use. The resources retain their identity, are kept in some
33
- * fast-access storage, and are re-used to avoid having to acquire them again. There are four main
34
- * caching strategies/techniques in this pattern; each with their own pros and cons. They are;
35
- * <code>write-through</code> which writes data to the cache and DB in a single transaction,
36
- * <code>write-around</code> which writes data immediately into the DB instead of the cache,
37
- * <code>write-behind</code> which writes data into the cache initially whilst the data is only
38
- * written into the DB when the cache is full, and <code>cache-aside</code> which pushes the
39
- * responsibility of keeping the data synchronized in both data sources to the application itself.
40
- * The <code>read-through</code> strategy is also included in the mentioned four strategies --
41
- * returns data from the cache to the caller <b>if</b> it exists <b>else</b> queries from DB and
42
- * stores it into the cache for future use. These strategies determine when the data in the cache
43
- * should be written back to the backing store (i.e. Database) and help keep both data sources
44
- * synchronized/up-to-date. This pattern can improve performance and also helps to maintain
45
- * consistency between data held in the cache and the data in the underlying data store.
8
+ * The Caching pattern describes how to avoid expensive re-acquisition of
9
+ * resources by not releasing the resources immediately after their use.
10
+ * The resources retain their identity, are kept in some fast-access storage,
11
+ * and are re-used to avoid having to acquire them again. There are four main
12
+ * caching strategies/techniques in this pattern; each with their own pros and
13
+ * cons. They are <code>write-through</code> which writes data to the cache and
14
+ * DB in a single transaction, <code>write-around</code> which writes data
15
+ * immediately into the DB instead of the cache, <code>write-behind</code>
16
+ * which writes data into the cache initially whilst the data is only
17
+ * written into the DB when the cache is full, and <code>cache-aside</code>
18
+ * which pushes the responsibility of keeping the data synchronized in both
19
+ * data sources to the application itself. The <code>read-through</code>
20
+ * strategy is also included in the mentioned four strategies --
21
+ * returns data from the cache to the caller <b>if</b> it exists <b>else</b>
22
+ * queries from DB and stores it into the cache for future use. These strategies
23
+ * determine when the data in the cache should be written back to the backing
24
+ * store (i.e. Database) and help keep both data sources
25
+ * synchronized/up-to-date. This pattern can improve performance and also helps
26
+ * to maintainconsistency between data held in the cache and the data in
27
+ * the underlying data store.
46
28
*
47
- * <p>In this example, the user account ({@link UserAccount}) entity is used as the underlying
48
- * application data. The cache itself is implemented as an internal (Java) data structure. It adopts
49
- * a Least-Recently-Used (LRU) strategy for evicting data from itself when its full. The four
50
- * strategies are individually tested. The testing of the cache is restricted towards saving and
51
- * querying of user accounts from the underlying data store ( {@link DbManager}). The main class (
52
- * {@link App} is not aware of the underlying mechanics of the application (i.e. save and query) and
53
- * whether the data is coming from the cache or the DB (i.e. separation of concern). The AppManager
54
- * ({@link AppManager}) handles the transaction of data to-and-from the underlying data store
55
- * (depending on the preferred caching policy/strategy).
29
+ * <p>In this example, the user account ({@link UserAccount}) entity is used
30
+ * as the underlying application data. The cache itself is implemented as an
31
+ * internal (Java) data structure. It adopts a Least-Recently-Used (LRU)
32
+ * strategy for evicting data from itself when its full. The four
33
+ * strategies are individually tested. The testing of the cache is restricted
34
+ * towards saving and querying of user accounts from the
35
+ * underlying data store( {@link DbManager}). The main class ( {@link App}
36
+ * is not aware of the underlying mechanics of the application
37
+ * (i.e. save and query) and whether the data is coming from the cache or the
38
+ * DB (i.e. separation of concern). The AppManager ({@link AppManager}) handles
39
+ * the transaction of data to-and-from the underlying data store (depending on
40
+ * the preferred caching policy/strategy).
56
41
* <p>
57
- * <i>{@literal App --> AppManager --> CacheStore/LRUCache/CachingPolicy --> DBManager} </i>
42
+ * <i>{@literal App --> AppManager --> CacheStore/LRUCache/CachingPolicy -->
43
+ * DBManager} </i>
58
44
* </p>
59
45
*
60
46
* <p>
68
54
*/
69
55
@ Slf4j
70
56
public class App {
57
+ /**
58
+ * Constant parameter name to use mongoDB.
59
+ */
71
60
private static final String USE_MONGO_DB = "--mongo" ;
72
- private AppManager appManager ;
61
+ /**
62
+ * Application manager.
63
+ */
64
+ private final AppManager appManager ;
73
65
74
- public App (boolean isMongo ) {
66
+ /**
67
+ * Constructor of current App.
68
+ * @param isMongo boolean
69
+ */
70
+ public App (final boolean isMongo ) {
75
71
DbManager dbManager = DbManagerFactory .initDb (isMongo );
76
72
appManager = new AppManager (dbManager );
77
73
appManager .initDb ();
@@ -82,28 +78,28 @@ public App(boolean isMongo) {
82
78
*
83
79
* @param args command line args
84
80
*/
85
- public static void main (String [] args ) {
81
+ public static void main (final String [] args ) {
86
82
// VirtualDB (instead of MongoDB) was used in running the JUnit tests
87
83
// and the App class to avoid Maven compilation errors. Set flag to
88
84
// true to run the tests with MongoDB (provided that MongoDB is
89
85
// installed and socket connection is open).
90
86
App app = new App (isDbMongo (args ));
91
87
app .useReadAndWriteThroughStrategy ();
92
- System .out .println ("===================================================== " );
88
+ System .out .println ("==============================================" );
93
89
app .useReadThroughAndWriteAroundStrategy ();
94
- System .out .println ("===================================================== " );
90
+ System .out .println ("==============================================" );
95
91
app .useReadThroughAndWriteBehindStrategy ();
96
- System .out .println ("===================================================== " );
92
+ System .out .println ("==============================================" );
97
93
app .useCacheAsideStategy ();
98
- System .out .println ("===================================================== " );
94
+ System .out .println ("==============================================" );
99
95
}
100
96
101
97
/**
102
98
* Check the input parameters. if
103
99
* @param args input params
104
100
* @return true if there is "--mongo" parameter in arguments
105
101
*/
106
- private static boolean isDbMongo (String [] args ) {
102
+ private static boolean isDbMongo (final String [] args ) {
107
103
for (String arg : args ) {
108
104
if (arg .equals (USE_MONGO_DB )) {
109
105
return true ;
@@ -156,17 +152,25 @@ public void useReadThroughAndWriteBehindStrategy() {
156
152
LOGGER .info ("# CachingPolicy.BEHIND" );
157
153
appManager .initCachingPolicy (CachingPolicy .BEHIND );
158
154
159
- var userAccount3 = new UserAccount ("003" , "Adam" , "He likes food." );
160
- var userAccount4 = new UserAccount ("004" , "Rita" , "She hates cats." );
161
- var userAccount5 = new UserAccount ("005" , "Isaac" , "He is allergic to mustard." );
155
+ var userAccount3 = new UserAccount ("003" ,
156
+ "Adam" ,
157
+ "He likes food." );
158
+ var userAccount4 = new UserAccount ("004" ,
159
+ "Rita" ,
160
+ "She hates cats." );
161
+ var userAccount5 = new UserAccount ("005" ,
162
+ "Isaac" ,
163
+ "He is allergic to mustard." );
162
164
163
165
appManager .save (userAccount3 );
164
166
appManager .save (userAccount4 );
165
167
appManager .save (userAccount5 );
166
168
LOGGER .info (appManager .printCacheContent ());
167
169
appManager .find ("003" );
168
170
LOGGER .info (appManager .printCacheContent ());
169
- UserAccount userAccount6 = new UserAccount ("006" , "Yasha" , "She is an only child." );
171
+ UserAccount userAccount6 = new UserAccount ("006" ,
172
+ "Yasha" ,
173
+ "She is an only child." );
170
174
appManager .save (userAccount6 );
171
175
LOGGER .info (appManager .printCacheContent ());
172
176
appManager .find ("004" );
@@ -181,9 +185,15 @@ public void useCacheAsideStategy() {
181
185
appManager .initCachingPolicy (CachingPolicy .ASIDE );
182
186
LOGGER .info (appManager .printCacheContent ());
183
187
184
- var userAccount3 = new UserAccount ("003" , "Adam" , "He likes food." );
185
- var userAccount4 = new UserAccount ("004" , "Rita" , "She hates cats." );
186
- var userAccount5 = new UserAccount ("005" , "Isaac" , "He is allergic to mustard." );
188
+ var userAccount3 = new UserAccount ("003" ,
189
+ "Adam" ,
190
+ "He likes food." );
191
+ var userAccount4 = new UserAccount ("004" ,
192
+ "Rita" ,
193
+ "She hates cats." );
194
+ var userAccount5 = new UserAccount ("005" ,
195
+ "Isaac" ,
196
+ "He is allergic to mustard." );
187
197
appManager .save (userAccount3 );
188
198
appManager .save (userAccount4 );
189
199
appManager .save (userAccount5 );
0 commit comments