From 33566805eeebee78512fc3380d33cd2cf168e196 Mon Sep 17 00:00:00 2001 From: Ilkka Seppala Date: Fri, 10 Apr 2015 20:24:16 +0300 Subject: [PATCH] Added Lazy Loading idiom. --- README.md | 14 ++++ lazy-loading/etc/lazy-loading.png | Bin 0 -> 11671 bytes lazy-loading/etc/lazy-loading.ucls | 66 ++++++++++++++++++ lazy-loading/pom.xml | 18 +++++ .../src/main/java/com/iluwatar/App.java | 33 +++++++++ .../src/main/java/com/iluwatar/Heavy.java | 19 +++++ .../main/java/com/iluwatar/HolderNaive.java | 23 ++++++ .../java/com/iluwatar/HolderThreadSafe.java | 24 +++++++ .../main/java/com/iluwatar/Java8Holder.java | 34 +++++++++ .../src/test/java/com/iluwatar/AppTest.java | 12 ++++ pom.xml | 5 +- 11 files changed, 246 insertions(+), 2 deletions(-) create mode 100644 lazy-loading/etc/lazy-loading.png create mode 100644 lazy-loading/etc/lazy-loading.ucls create mode 100644 lazy-loading/pom.xml create mode 100644 lazy-loading/src/main/java/com/iluwatar/App.java create mode 100644 lazy-loading/src/main/java/com/iluwatar/Heavy.java create mode 100644 lazy-loading/src/main/java/com/iluwatar/HolderNaive.java create mode 100644 lazy-loading/src/main/java/com/iluwatar/HolderThreadSafe.java create mode 100644 lazy-loading/src/main/java/com/iluwatar/Java8Holder.java create mode 100644 lazy-loading/src/test/java/com/iluwatar/AppTest.java 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. + +![alt text](https://github.com/iluwatar/java-design-patterns/blob/master/lazy-loading/etc/lazy-loading.png "Lazy Loading") + +**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 0000000000000000000000000000000000000000..bec0a7afbefe08d3741e4f2b5c4043c62977790e GIT binary patch literal 11671 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 HHVODIUz$3B literal 0 HcmV?d00001 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