diff --git a/pom.xml b/pom.xml
index 482110e64..c15ca20cf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -120,6 +120,7 @@
delegation
event-driven-architecture
feature-toggle
+ value-object
@@ -199,8 +200,8 @@
-
org.eclipse.m2e
@@ -256,10 +257,10 @@
org.jacoco
jacoco-maven-plugin
${jacoco.version}
-
-
@@ -354,7 +355,7 @@
exclude-pmd.properties
-
+
@@ -390,5 +391,5 @@
-
+
diff --git a/value-object/etc/value-object.png b/value-object/etc/value-object.png
new file mode 100644
index 000000000..69a244c80
Binary files /dev/null and b/value-object/etc/value-object.png differ
diff --git a/value-object/etc/value-object.ucls b/value-object/etc/value-object.ucls
new file mode 100644
index 000000000..7bbf5e47c
--- /dev/null
+++ b/value-object/etc/value-object.ucls
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/value-object/index.md b/value-object/index.md
new file mode 100644
index 000000000..83223d8a2
--- /dev/null
+++ b/value-object/index.md
@@ -0,0 +1,34 @@
+---
+layout: pattern
+title: Value Object
+folder: value-object
+permalink: /patterns/value-object/
+categories: Creational
+tags:
+ - Java
+ - Difficulty-Beginner
+---
+
+## Intent
+Provide objects which follow value semantics rather than reference semantics.
+This means value objects' equality are not based on identity. Two value objects are
+equal when they have the same value, not necessarily being the same object.
+
+
+
+## Applicability
+Use the Value Object when
+
+* you need to measure the objects' equality based on the objects' value
+
+## Real world examples
+
+* [java.util.Optional](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html)
+* [java.time.LocalDate](https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html)
+* [joda-time, money, beans](http://www.joda.org/)
+
+## Credits
+
+* [Patterns of Enterprise Application Architecture](http://www.martinfowler.com/books/eaa.html)
+* [VALJOs - Value Java Objects : Stephen Colebourne's blog](http://blog.joda.org/2014/03/valjos-value-java-objects.html)
+* [Value Object : Wikipedia](https://en.wikipedia.org/wiki/Value_object)
diff --git a/value-object/pom.xml b/value-object/pom.xml
new file mode 100644
index 000000000..1ed2adb43
--- /dev/null
+++ b/value-object/pom.xml
@@ -0,0 +1,30 @@
+
+
+ 4.0.0
+
+ com.iluwatar
+ java-design-patterns
+ 1.11.0-SNAPSHOT
+
+ value-object
+
+
+ com.google.guava
+ guava-testlib
+ 19.0
+ test
+
+
+ junit
+ junit
+ test
+
+
+ org.mockito
+ mockito-core
+ test
+
+
+
diff --git a/value-object/src/main/java/com/iluwatar/value/object/App.java b/value-object/src/main/java/com/iluwatar/value/object/App.java
new file mode 100644
index 000000000..85779fcb7
--- /dev/null
+++ b/value-object/src/main/java/com/iluwatar/value/object/App.java
@@ -0,0 +1,32 @@
+package com.iluwatar.value.object;
+
+/**
+ * A Value Object are objects which follow value semantics rather than reference semantics. This
+ * means value objects' equality are not based on identity. Two value objects are equal when they
+ * have the same value, not necessarily being the same object..
+ *
+ * Value Objects must override equals(), hashCode() to check the equality with values.
+ * Value Objects should be immutable so declare members final.
+ * Obtain instances by static factory methods.
+ * The elements of the state must be other values, including primitive types.
+ * Provide methods, typically simple getters, to get the elements of the state.
+ * A Value Object must check equality with equals() not ==
+ *
+ * For more specific and strict rules to implement value objects check the rules from Stephen
+ * Colebourne's term VALJO : http://blog.joda.org/2014/03/valjos-value-java-objects.html
+ */
+public class App {
+ /**
+ * This practice creates three HeroStats(Value object) and checks equality between those.
+ */
+ public static void main(String[] args) {
+ HeroStat statA = HeroStat.valueOf(10, 5, 0);
+ HeroStat statB = HeroStat.valueOf(10, 5, 0);
+ HeroStat statC = HeroStat.valueOf(5, 1, 8);
+
+ System.out.println(statA.toString());
+
+ System.out.println("Is statA and statB equal : " + statA.equals(statB));
+ System.out.println("Is statA and statC equal : " + statA.equals(statC));
+ }
+}
diff --git a/value-object/src/main/java/com/iluwatar/value/object/HeroStat.java b/value-object/src/main/java/com/iluwatar/value/object/HeroStat.java
new file mode 100644
index 000000000..101837db0
--- /dev/null
+++ b/value-object/src/main/java/com/iluwatar/value/object/HeroStat.java
@@ -0,0 +1,90 @@
+package com.iluwatar.value.object;
+
+/**
+ * HeroStat is a value object
+ *
+ * {@link http://docs.oracle.com/javase/8/docs/api/java/lang/doc-files/ValueBased.html}
+ */
+public class HeroStat {
+
+ // Stats for a hero
+
+ private final int strength;
+ private final int intelligence;
+ private final int luck;
+
+ // All constructors must be private.
+ private HeroStat(int strength, int intelligence, int luck) {
+ super();
+ this.strength = strength;
+ this.intelligence = intelligence;
+ this.luck = luck;
+ }
+
+ // Static factory method to create new instances.
+ public static HeroStat valueOf(int strength, int intelligence, int luck) {
+ return new HeroStat(strength, intelligence, luck);
+ }
+
+ public int getStrength() {
+ return strength;
+ }
+
+ public int getIntelligence() {
+ return intelligence;
+ }
+
+ public int getLuck() {
+ return luck;
+ }
+
+ /*
+ * Recommended to provide a static factory method capable of creating an instance from the formal
+ * string representation declared like this. public static HeroStat parse(String string) {}
+ */
+
+ // toString, hashCode, equals
+
+ @Override
+ public String toString() {
+ return "HeroStat [strength=" + strength + ", intelligence=" + intelligence
+ + ", luck=" + luck + "]";
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + intelligence;
+ result = prime * result + luck;
+ result = prime * result + strength;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ HeroStat other = (HeroStat) obj;
+ if (intelligence != other.intelligence) {
+ return false;
+ }
+ if (luck != other.luck) {
+ return false;
+ }
+ if (strength != other.strength) {
+ return false;
+ }
+ return true;
+ }
+
+ // The clone() method should not be public. Just don't override it.
+
+}
diff --git a/value-object/src/test/java/com/iluwatar/value/object/AppTest.java b/value-object/src/test/java/com/iluwatar/value/object/AppTest.java
new file mode 100644
index 000000000..aed3c2f20
--- /dev/null
+++ b/value-object/src/test/java/com/iluwatar/value/object/AppTest.java
@@ -0,0 +1,15 @@
+package com.iluwatar.value.object;
+
+import org.junit.Test;
+
+/**
+ * Application test
+ */
+public class AppTest {
+
+ @Test
+ public void test() {
+ String[] args = {};
+ App.main(args);
+ }
+}
diff --git a/value-object/src/test/java/com/iluwatar/value/object/HeroStatTest.java b/value-object/src/test/java/com/iluwatar/value/object/HeroStatTest.java
new file mode 100644
index 000000000..785a4d8fe
--- /dev/null
+++ b/value-object/src/test/java/com/iluwatar/value/object/HeroStatTest.java
@@ -0,0 +1,44 @@
+package com.iluwatar.value.object;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+
+import static org.junit.Assert.assertThat;
+
+import com.google.common.testing.EqualsTester;
+
+import org.junit.Test;
+
+/**
+ * Unit test for HeroStat.
+ */
+public class HeroStatTest {
+
+ /**
+ * Tester for equals() and hashCode() methods of a class. Using guava's EqualsTester.
+ *
+ * @see http://static.javadoc.io/com.google.guava/guava-testlib/19.0/com/google/common/testing/
+ * EqualsTester.html
+ */
+ @Test
+ public void testEquals() {
+ HeroStat heroStatA = HeroStat.valueOf(3, 9, 2);
+ HeroStat heroStatB = HeroStat.valueOf(3, 9, 2);
+ new EqualsTester().addEqualityGroup(heroStatA, heroStatB).testEquals();
+ }
+
+ /**
+ * The toString() for two equal values must be the same. For two non-equal values it must be
+ * different.
+ */
+ @Test
+ public void testToString() {
+ HeroStat heroStatA = HeroStat.valueOf(3, 9, 2);
+ HeroStat heroStatB = HeroStat.valueOf(3, 9, 2);
+ HeroStat heroStatC = HeroStat.valueOf(3, 9, 8);
+
+ assertThat(heroStatA.toString(), is(heroStatB.toString()));
+ assertThat(heroStatA.toString(), is(not(heroStatC.toString())));
+ }
+
+}