diff --git a/README.md b/README.md
index ddcd4a87e..2d6d3456a 100644
--- a/README.md
+++ b/README.md
@@ -72,6 +72,7 @@ A programming idiom is a means of expressing a recurring construct in one or mor
* [Double Checked Locking](#double-checked-locking)
* [Poison Pill](#poison-pill)
* [Callback](#callback)
+* [Lazy Loading](#lazy-loading)
## Abstract Factory [↑](#list-of-design-patterns)
**Intent:** Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
@@ -482,6 +483,19 @@ A programming idiom is a means of expressing a recurring construct in one or mor
**Applicability:** Use the Poison Pill idiom when
* need to send signal from one thread/process to another to terminate
+## Lazy Loading [↑](#list-of-design-patterns)
+**Intent:** Lazy loading is a design pattern commonly used to defer initialization of an object until the point at which it is needed. It can contribute to efficiency in the program's operation if properly and appropriately used.
+
+
+
+**Applicability:** Use the Lazy Loading idiom when
+* eager loading is expensive or the object to be loaded might not be need at all
+
+**Real world examples:**
+* JPA annotations @OneToOne, @OneToMany, @ManyToOne, @ManyToMany and fetch = FetchType.LAZY
+
+
+
# Frequently asked questions
**Q: What is the difference between State and Strategy patterns?**
diff --git a/lazy-loading/etc/lazy-loading.png b/lazy-loading/etc/lazy-loading.png
new file mode 100644
index 000000000..bec0a7afb
Binary files /dev/null and b/lazy-loading/etc/lazy-loading.png differ
diff --git a/lazy-loading/etc/lazy-loading.ucls b/lazy-loading/etc/lazy-loading.ucls
new file mode 100644
index 000000000..9f4ccd1a4
--- /dev/null
+++ b/lazy-loading/etc/lazy-loading.ucls
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/lazy-loading/pom.xml b/lazy-loading/pom.xml
new file mode 100644
index 000000000..64cb34822
--- /dev/null
+++ b/lazy-loading/pom.xml
@@ -0,0 +1,18 @@
+
+
+ 4.0.0
+
+ com.iluwatar
+ java-design-patterns
+ 1.0-SNAPSHOT
+
+ lazy-loading
+
+
+ junit
+ junit
+ test
+
+
+
diff --git a/lazy-loading/src/main/java/com/iluwatar/App.java b/lazy-loading/src/main/java/com/iluwatar/App.java
new file mode 100644
index 000000000..c0f4b0591
--- /dev/null
+++ b/lazy-loading/src/main/java/com/iluwatar/App.java
@@ -0,0 +1,33 @@
+package com.iluwatar;
+
+/**
+ *
+ * Lazy loading idiom defers object creation until needed.
+ *
+ * This example shows different implementations of the pattern
+ * with increasing sophistication.
+ *
+ * Additional information and lazy loading flavours are described in
+ * http://martinfowler.com/eaaCatalog/lazyLoad.html
+ *
+ */
+public class App
+{
+ public static void main( String[] args ) {
+
+ // Simple lazy loader - not thread safe
+ HolderNaive holderNaive = new HolderNaive();
+ Heavy heavy = holderNaive.getHeavy();
+ System.out.println("heavy=" + heavy);
+
+ // Thread safe lazy loader, but with heavy synchronization on each access
+ HolderThreadSafe holderThreadSafe = new HolderThreadSafe();
+ Heavy another = holderThreadSafe.getHeavy();
+ System.out.println("another=" + another);
+
+ // The most efficient lazy loader utilizing Java 8 features
+ Java8Holder java8Holder = new Java8Holder();
+ Heavy next = java8Holder.getHeavy();
+ System.out.println("next=" + next);
+ }
+}
diff --git a/lazy-loading/src/main/java/com/iluwatar/Heavy.java b/lazy-loading/src/main/java/com/iluwatar/Heavy.java
new file mode 100644
index 000000000..534b83c9e
--- /dev/null
+++ b/lazy-loading/src/main/java/com/iluwatar/Heavy.java
@@ -0,0 +1,19 @@
+package com.iluwatar;
+
+/**
+ *
+ * Heavy objects are expensive to create.
+ *
+ */
+public class Heavy {
+
+ public Heavy() {
+ System.out.println("Creating Heavy ...");
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ System.out.println("... Heavy created");
+ }
+}
diff --git a/lazy-loading/src/main/java/com/iluwatar/HolderNaive.java b/lazy-loading/src/main/java/com/iluwatar/HolderNaive.java
new file mode 100644
index 000000000..b741cb7d5
--- /dev/null
+++ b/lazy-loading/src/main/java/com/iluwatar/HolderNaive.java
@@ -0,0 +1,23 @@
+package com.iluwatar;
+
+/**
+ *
+ * Simple implementation of the lazy loading idiom.
+ * However, this is not thread safe.
+ *
+ */
+public class HolderNaive {
+
+ private Heavy heavy;
+
+ public HolderNaive() {
+ System.out.println("HolderNaive created");
+ }
+
+ public Heavy getHeavy() {
+ if (heavy == null) {
+ heavy = new Heavy();
+ }
+ return heavy;
+ }
+}
diff --git a/lazy-loading/src/main/java/com/iluwatar/HolderThreadSafe.java b/lazy-loading/src/main/java/com/iluwatar/HolderThreadSafe.java
new file mode 100644
index 000000000..ef8282bd3
--- /dev/null
+++ b/lazy-loading/src/main/java/com/iluwatar/HolderThreadSafe.java
@@ -0,0 +1,24 @@
+package com.iluwatar;
+
+/**
+ *
+ * Same as HolderNaive but with added synchronization.
+ * This implementation is thread safe, but each {@link #getHeavy()}
+ * call costs additional synchronization overhead.
+ *
+ */
+public class HolderThreadSafe {
+
+ private Heavy heavy;
+
+ public HolderThreadSafe() {
+ System.out.println("HolderThreadSafe created");
+ }
+
+ public synchronized Heavy getHeavy() {
+ if (heavy == null) {
+ heavy = new Heavy();
+ }
+ return heavy;
+ }
+}
diff --git a/lazy-loading/src/main/java/com/iluwatar/Java8Holder.java b/lazy-loading/src/main/java/com/iluwatar/Java8Holder.java
new file mode 100644
index 000000000..c0241592a
--- /dev/null
+++ b/lazy-loading/src/main/java/com/iluwatar/Java8Holder.java
@@ -0,0 +1,34 @@
+package com.iluwatar;
+
+import java.util.function.Supplier;
+
+/**
+ *
+ * This lazy loader is thread safe and more efficient than HolderThreadSafe.
+ * It utilizes Java 8 functional interface Supplier as Heavy factory.
+ *
+ */
+public class Java8Holder {
+
+ private Supplier heavy = () -> createAndCacheHeavy();
+
+ public Java8Holder() {
+ System.out.println("Java8Holder created");
+ }
+
+ public Heavy getHeavy() {
+ return heavy.get();
+ }
+
+ private synchronized Heavy createAndCacheHeavy() {
+ class HeavyFactory implements Supplier {
+ private final Heavy heavyInstance = new Heavy();
+ @Override
+ public Heavy get() { return heavyInstance; }
+ }
+ if (!HeavyFactory.class.isInstance(heavy)) {
+ heavy = new HeavyFactory();
+ }
+ return heavy.get();
+ }
+}
diff --git a/lazy-loading/src/test/java/com/iluwatar/AppTest.java b/lazy-loading/src/test/java/com/iluwatar/AppTest.java
new file mode 100644
index 000000000..6db5ad214
--- /dev/null
+++ b/lazy-loading/src/test/java/com/iluwatar/AppTest.java
@@ -0,0 +1,12 @@
+package com.iluwatar;
+
+import org.junit.Test;
+
+public class AppTest {
+
+ @Test
+ public void test() {
+ String[] args = {};
+ App.main(args);
+ }
+}
diff --git a/pom.xml b/pom.xml
index 8d5423d13..33b34296f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -45,7 +45,8 @@
property
intercepting-filter
poison-pill
-
+ lazy-loading
+
@@ -73,4 +74,4 @@
-
+
\ No newline at end of file