-
-
Notifications
You must be signed in to change notification settings - Fork 27k
Value object pattern #349 #362
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
64b89ec
Create project for value-object pattern
JuhoKang cca40a5
Added Code
JuhoKang 083065b
Added index.md
JuhoKang d3eb8a2
Added comments in the code. modified index.md
JuhoKang 3ef4649
Merge remote-tracking branch 'upstream/master', fixed f-c index properly
JuhoKang 0e7fae2
Edit pom.xml
JuhoKang d837891
pom.xml change to fit upstream
JuhoKang 1e5cbe1
Merge remote-tracking branch 'upstream/master'
JuhoKang 0498412
deleted the change in parent pom
JuhoKang db2140e
updated child and parent pom
JuhoKang f71e186
Fixed descriptions in code.
JuhoKang 8353354
format code
JuhoKang File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<class-diagram version="1.1.9" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true" | ||
realizations="true" associations="true" dependencies="true" nesting-relationships="true" router="FAN"> | ||
<class id="1" language="java" name="com.iluwatar.value.object.HeroStat" project="value-object" | ||
file="/value-object/src/main/java/com/iluwatar/value/object/HeroStat.java" binary="false" corner="BOTTOM_RIGHT"> | ||
<position height="-1" width="-1" x="520" y="337"/> | ||
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" | ||
sort-features="false" accessors="true" visibility="true"> | ||
<attributes public="true" package="true" protected="true" private="true" static="true"/> | ||
<operations public="true" package="true" protected="true" private="true" static="true"/> | ||
</display> | ||
</class> | ||
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true" | ||
sort-features="false" accessors="true" visibility="true"> | ||
<attributes public="true" package="true" protected="true" private="true" static="true"/> | ||
<operations public="true" package="true" protected="true" private="true" static="true"/> | ||
</classifier-display> | ||
<association-display labels="true" multiplicity="true"/> | ||
</class-diagram> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?xml version="1.0"?> | ||
<project | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" | ||
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>com.iluwatar</groupId> | ||
<artifactId>java-design-patterns</artifactId> | ||
<version>1.11.0-SNAPSHOT</version> | ||
</parent> | ||
<artifactId>value-object</artifactId> | ||
<dependencies> | ||
<dependency> | ||
<groupId>com.google.guava</groupId> | ||
<artifactId>guava-testlib</artifactId> | ||
<version>19.0</version> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>junit</groupId> | ||
<artifactId>junit</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.mockito</groupId> | ||
<artifactId>mockito-core</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
</project> |
32 changes: 32 additions & 0 deletions
32
value-object/src/main/java/com/iluwatar/value/object/App.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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)); | ||
} | ||
} |
90 changes: 90 additions & 0 deletions
90
value-object/src/main/java/com/iluwatar/value/object/HeroStat.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. | ||
|
||
} |
15 changes: 15 additions & 0 deletions
15
value-object/src/test/java/com/iluwatar/value/object/AppTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
value-object/src/test/java/com/iluwatar/value/object/HeroStatTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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()))); | ||
} | ||
|
||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know why these blanks exist and make differences in this file. I only added one line value-object.