Skip to content

Commit 6e9b565

Browse files
authored
Merge pull request #17238 from etrandafir93/features/BAEL-8199-ddd_jmolecules
BAEL-8199: jMolecules DDD
2 parents c4fd58c + d047012 commit 6e9b565

File tree

8 files changed

+266
-3
lines changed

8 files changed

+266
-3
lines changed

patterns-modules/ddd/pom.xml

+35-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<project xmlns="http://maven.apache.org/POM/4.0.0"
3-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
55
<modelVersion>4.0.0</modelVersion>
66
<artifactId>ddd</artifactId>
77
<name>ddd</name>
@@ -61,6 +61,31 @@
6161
<groupId>org.springframework.boot</groupId>
6262
<artifactId>spring-boot-starter-validation</artifactId>
6363
</dependency>
64+
65+
<dependency>
66+
<groupId>org.jmolecules.integrations</groupId>
67+
<artifactId>jmolecules-starter-ddd</artifactId>
68+
<version>${jmolecules-integration.version}</version>
69+
</dependency>
70+
<dependency>
71+
<groupId>org.jmolecules.integrations</groupId>
72+
<artifactId>jmolecules-starter-test</artifactId>
73+
<version>${jmolecules-integration.version}</version>
74+
<scope>test</scope>
75+
</dependency>
76+
<dependency>
77+
<groupId>org.jmolecules</groupId>
78+
<artifactId>jmolecules-archunit</artifactId>
79+
<version>${jmolecules-archunit.version}</version>
80+
<scope>test</scope>
81+
</dependency>
82+
<dependency>
83+
<groupId>com.tngtech.archunit</groupId>
84+
<artifactId>archunit</artifactId>
85+
<version>${archunit.version}</version>
86+
<scope>test</scope>
87+
</dependency>
88+
6489
<dependency>
6590
<groupId>org.springframework.boot</groupId>
6691
<artifactId>spring-boot-starter-test</artifactId>
@@ -75,9 +100,16 @@
75100
</dependencies>
76101

77102
<properties>
103+
<java.version>17</java.version>
104+
<maven.compiler.source>17</maven.compiler.source>
105+
<maven.compiler.target>17</maven.compiler.target>
106+
78107
<start-class>com.baeldung.ddd.PersistingDddAggregatesApplication</start-class>
79108
<joda-money.version>1.0.1</joda-money.version>
80109
<de.flapdoodle.embed.mongo.version>4.11.1</de.flapdoodle.embed.mongo.version>
110+
<jmolecules-integration.version>0.21.0</jmolecules-integration.version>
111+
<jmolecules-archunit.version>1.0.0</jmolecules-archunit.version>
112+
<archunit.version>1.3.0</archunit.version>
81113
</properties>
82114

83-
</project>
115+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package com.baeldung.dddjmolecules.article;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collections;
5+
import java.util.List;
6+
7+
import org.jmolecules.ddd.annotation.AggregateRoot;
8+
import org.jmolecules.ddd.annotation.Identity;
9+
10+
import com.baeldung.dddjmolecules.author.Username;
11+
12+
@AggregateRoot
13+
public class Article {
14+
@Identity
15+
private Slug slug;
16+
private Username author;
17+
private String title;
18+
private String content;
19+
private Status status;
20+
private List<Comment> comments;
21+
private List<Username> likedBy;
22+
23+
enum Status {
24+
DRAFT, PUBLISHED, HIDDEN, ARCHIVED
25+
}
26+
27+
public Article(Username author, String content, String title) {
28+
this.status = Status.DRAFT;
29+
this.author = author;
30+
this.title = title;
31+
this.content = content;
32+
this.slug = new Slug(title.toLowerCase()
33+
.replaceAll(" ", "-"));
34+
this.comments = new ArrayList<>();
35+
this.likedBy = new ArrayList<>();
36+
}
37+
38+
void publish() {
39+
if (status == Status.DRAFT || status == Status.HIDDEN) {
40+
status = Status.PUBLISHED;
41+
}
42+
throw new IllegalStateException("we cannot publish an article with status=" + status);
43+
}
44+
45+
void hide() {
46+
if (status == Status.PUBLISHED) {
47+
status = Status.HIDDEN;
48+
}
49+
throw new IllegalStateException("we cannot hide an article with status=" + status);
50+
}
51+
52+
void archive() {
53+
if (status != Status.ARCHIVED) {
54+
status = Status.ARCHIVED;
55+
}
56+
throw new IllegalStateException("the article is already archived");
57+
}
58+
59+
void comment(Username user, String message) {
60+
comments.add(new Comment(user, message));
61+
}
62+
63+
void like(Username user) {
64+
likedBy.add(user);
65+
}
66+
67+
void dislike(Username user) {
68+
likedBy.remove(user);
69+
}
70+
71+
public Slug getSlug() {
72+
return slug;
73+
}
74+
75+
public Username getAuthor() {
76+
return author;
77+
}
78+
79+
public String getTitle() {
80+
return title;
81+
}
82+
83+
public String getContent() {
84+
return content;
85+
}
86+
87+
public Status getStatus() {
88+
return status;
89+
}
90+
91+
public List<Comment> getComments() {
92+
return Collections.unmodifiableList(comments);
93+
}
94+
95+
public List<Username> getLikedBy() {
96+
return Collections.unmodifiableList(likedBy);
97+
}
98+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.baeldung.dddjmolecules.article;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.Optional;
6+
7+
import org.jmolecules.ddd.annotation.Repository;
8+
9+
import com.baeldung.dddjmolecules.article.Article.Status;
10+
11+
@Repository
12+
public class Articles {
13+
Slug save(Article draft) {
14+
// save to DB
15+
return draft.getSlug();
16+
}
17+
18+
Optional<Article> find(Slug slug) {
19+
// query DB
20+
return Optional.empty();
21+
}
22+
23+
List<Article> filterByStatus(Status status) {
24+
// query DB
25+
return new ArrayList<>();
26+
}
27+
28+
void remove(Slug article) {
29+
// update DB and mark as removed
30+
}
31+
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.baeldung.dddjmolecules.article;
2+
3+
import java.time.Instant;
4+
import java.util.UUID;
5+
6+
import org.jmolecules.ddd.annotation.Entity;
7+
import org.jmolecules.ddd.annotation.Identity;
8+
9+
import com.baeldung.dddjmolecules.author.Username;
10+
11+
@Entity
12+
public class Comment {
13+
@Identity
14+
private final String id;
15+
private final Username author;
16+
private String message;
17+
private Instant lastModified;
18+
19+
Comment(Username author, String message) {
20+
this.id = UUID.randomUUID()
21+
.toString();
22+
this.author = author;
23+
this.message = message;
24+
this.lastModified = Instant.now();
25+
}
26+
27+
public void edit(String newMessage) {
28+
this.message = newMessage;
29+
this.lastModified = Instant.now();
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.baeldung.dddjmolecules.article;
2+
3+
import org.jmolecules.ddd.annotation.ValueObject;
4+
import org.springframework.util.Assert;
5+
6+
@ValueObject
7+
public class Slug {
8+
private final String value;
9+
10+
Slug(String value) {
11+
Assert.isTrue(value != null, "Article's slug cannot be null!");
12+
Assert.isTrue(value.length() >= 5, "Article's slug should be at least 5 characters long!");
13+
this.value = value;
14+
}
15+
16+
public String value() {
17+
return value;
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.baeldung.dddjmolecules.author;
2+
3+
import org.jmolecules.ddd.annotation.AggregateRoot;
4+
import org.jmolecules.ddd.annotation.Identity;
5+
import org.jmolecules.ddd.annotation.ValueObject;
6+
7+
import com.baeldung.dddjmolecules.article.Slug;
8+
9+
@AggregateRoot
10+
public class Author {
11+
@Identity
12+
private Username username;
13+
private Email email;
14+
private Slug latestArticle;
15+
16+
@ValueObject
17+
record Email(String address) {
18+
}
19+
20+
// constructor, getters, setters
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.baeldung.dddjmolecules.author;
2+
3+
import org.jmolecules.ddd.annotation.ValueObject;
4+
import org.springframework.util.Assert;
5+
6+
@ValueObject
7+
public record Username(String value) {
8+
public Username {
9+
Assert.isTrue(value != null && !value.isBlank(), "Username value cannot be null or blank.");
10+
}
11+
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.baeldung.dddjmolecules;
2+
3+
import org.jmolecules.archunit.JMoleculesDddRules;
4+
5+
import com.tngtech.archunit.core.domain.JavaClasses;
6+
import com.tngtech.archunit.junit.AnalyzeClasses;
7+
import com.tngtech.archunit.junit.ArchTest;
8+
9+
@AnalyzeClasses(packages = "com.baeldung.dddjmolecules")
10+
class JMoleculesDddUnitTest {
11+
12+
@ArchTest
13+
void whenCheckingAllClasses_thenCodeFollowsAllDddPrinciples(JavaClasses classes) {
14+
JMoleculesDddRules.all()
15+
.check(classes);
16+
}
17+
}
18+

0 commit comments

Comments
 (0)