Skip to content

Commit 777a5dc

Browse files
committed
iluwatar#2373 add: Vertical Slice Architecture.
1 parent cb2d794 commit 777a5dc

30 files changed

+1355
-0
lines changed

pom.xml

+1
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@
207207
<module>context-object</module>
208208
<module>thread-local-storage</module>
209209
<module>optimistic-offline-lock</module>
210+
<module>vertical-slice-architecture</module>
210211
</modules>
211212
<repositories>
212213
<repository>

vertical-slice-architecture/README.md

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
title: Vertical-Slice-Architecture
3+
aka: Layer-By-Feature
4+
category: Architectural
5+
language: en
6+
tag:
7+
- Decoupling
8+
---
9+
10+
## Intent
11+
12+
package the application based on features. Each feature will have its own set of layers (
13+
Models, Services, Repository and Controllers ).
14+
15+
## Explanation
16+
17+
> With vertical slice architecture we can have high cohesion within package and low coupling
18+
> among the packages. In Conceptual term
19+
20+
> Consider that you are going to make a backend service for a online e-commerce application.
21+
> initially you make it with usual grouping of controllers, models etc. but as the application
22+
> grows more it's requires implementation of new features. Let's say that you thought of having
23+
> orders, customers and products associated layers. But now you need to include another set of
24+
> features with Cart system and wishlists. Now it's really hard to integrate those features it
25+
> requires lot's of dependency modifications and mocking. So if you make the package by feature
26+
> it will be really feasible for future additions. General example.
27+
28+
## Class diagram
29+
30+
![Vertical Slice Architecture](./etc/vertical-slice-architecture.urm.png)
31+
32+
## Applicability
33+
34+
Use Vertical Slice Architecture when
35+
36+
* You want future modification ( new addition of features ).
37+
* You want to reduce the amount of mocking.
38+
* You want to make it more modular by feature.
39+
40+
## Resources
41+
42+
* [How to Implement Vertical Slice Architecture by Gary Woodfine](https://garywoodfine.com/implementing-vertical-slice-architecture/)
43+
* [youtube](https://www.youtube.com/watch?v=B1d95I7-zsw)
44+
* [medium](https://medium.com/sahibinden-technology/package-by-layer-vs-package-by-feature-7e89cde2ae3a)
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
@startuml
2+
package com.iluwatar.vertical-slice-architecture {
3+
4+
!define ENTITY class
5+
!define SERVICE class
6+
!define REPOSITORY class
7+
!define VIEW class
8+
9+
package Customer {
10+
ENTITY Customer {
11+
+id: int
12+
name: String
13+
email: String
14+
+getId(): int
15+
+getName(): String
16+
+getEmail(): String
17+
+builder(): Builder
18+
}
19+
20+
SERVICE CustomerService {
21+
+createCustomer(name: String, email: String): Customer
22+
+getCustomerById(id: int): Customer
23+
+getAllCustomers(): List<Customer>
24+
}
25+
26+
REPOSITORY CustomerRepository {
27+
+save(customer: Customer): Customer
28+
+findById(id: int): Optional<Customer>
29+
+findAll(): List<Customer>
30+
}
31+
32+
33+
VIEW CustomerView {
34+
-customerService: CustomerService
35+
-LOGGER: logger
36+
+render(): void
37+
}
38+
}
39+
40+
package Product {
41+
ENTITY Product {
42+
+id: int
43+
name: String
44+
price: double
45+
+getId(): int
46+
+getName(): String
47+
+getPrice(): Double
48+
+builder(): Builder
49+
}
50+
51+
SERVICE ProductService {
52+
+createProduct(name: String, price: double): Product
53+
+getProductById(id: int): Product
54+
+getAllProducts(): List<Product>
55+
}
56+
57+
REPOSITORY ProductRepository {
58+
+save(product: Product): Product
59+
+findById(id: int): Optional<Product>
60+
+findAll(): List<Product>
61+
}
62+
63+
64+
VIEW ProductView {
65+
-productService: ProductService
66+
-LOGGER: logger
67+
+render(): void
68+
}
69+
}
70+
71+
package Order {
72+
ENTITY Orders {
73+
+id: int
74+
customer: Customer
75+
product: Product
76+
+getId(): int
77+
+getCustomer(): Customer
78+
+getProduct(): Product
79+
+builder(): Builder
80+
}
81+
82+
SERVICE OrderService {
83+
+createOrder(customer: Customer, product: Product): void
84+
+getOrderById(id: int): Orders
85+
+getOrdersByCustomer(customer: Customer): List<Orders>
86+
}
87+
88+
REPOSITORY OrderRepository {
89+
+save(order: Orders): Orders
90+
+findById(id: int): Optional<Orders>
91+
+findByCustomer(customer: Customer): List<Orders>
92+
}
93+
94+
95+
VIEW OrderView {
96+
-orderService: OrderService
97+
-LOGGER: logger
98+
+render(customer: Customer): void
99+
+showAllOrders(orders: List<Orders>): void
100+
}
101+
}
102+
103+
class App {
104+
+initializeData(): void
105+
+run(): void
106+
}
107+
108+
Customer.Customer --> Customer.CustomerService
109+
Customer.CustomerService --> Customer.CustomerRepository
110+
Customer.CustomerService --> Customer.CustomerView
111+
112+
Product.Product --> Product.ProductService
113+
Product.ProductService --> Product.ProductRepository
114+
Product.ProductService --> Product.ProductView
115+
116+
Order.Orders --> Order.OrderService
117+
Order.OrderService --> Order.OrderRepository
118+
Order.OrderService --> Order.OrderView
119+
120+
App --> Customer.CustomerService
121+
App --> Product.ProductService
122+
App --> Order.OrderService
123+
124+
}
125+
@enduml

vertical-slice-architecture/pom.xml

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
5+
6+
The MIT License
7+
Copyright © 2014-2022 Ilkka Seppälä
8+
9+
Permission is hereby granted, free of charge, to any person obtaining a copy
10+
of this software and associated documentation files (the "Software"), to deal
11+
in the Software without restriction, including without limitation the rights
12+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
copies of the Software, and to permit persons to whom the Software is
14+
furnished to do so, subject to the following conditions:
15+
16+
The above copyright notice and this permission notice shall be included in
17+
all copies or substantial portions of the Software.
18+
19+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
THE SOFTWARE.
26+
27+
-->
28+
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
29+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
30+
<modelVersion>4.0.0</modelVersion>
31+
<artifactId>vertical-slice-architecture</artifactId>
32+
<parent>
33+
<groupId>com.iluwatar</groupId>
34+
<artifactId>java-design-patterns</artifactId>
35+
<version>1.26.0-SNAPSHOT</version>
36+
</parent>
37+
<dependencies>
38+
<dependency>
39+
<groupId>org.springframework.boot</groupId>
40+
<artifactId>spring-boot-starter-web</artifactId>
41+
</dependency>
42+
<dependency>
43+
<groupId>org.springframework.boot</groupId>
44+
<artifactId>spring-boot-starter-test</artifactId>
45+
<scope>test</scope>
46+
</dependency>
47+
<dependency>
48+
<groupId>org.springframework.boot</groupId>
49+
<artifactId>spring-boot-starter-data-jpa</artifactId>
50+
</dependency>
51+
<dependency>
52+
<groupId>com.h2database</groupId>
53+
<artifactId>h2</artifactId>
54+
<scope>runtime</scope>
55+
</dependency>
56+
57+
</dependencies>
58+
59+
<build>
60+
<plugins>
61+
<plugin>
62+
<groupId>org.springframework.boot</groupId>
63+
<artifactId>spring-boot-maven-plugin</artifactId>
64+
<executions>
65+
<execution>
66+
<goals>
67+
<goal>repackage</goal>
68+
</goals>
69+
</execution>
70+
</executions>
71+
</plugin>
72+
<plugin>
73+
<groupId>org.apache.maven.plugins</groupId>
74+
<artifactId>maven-assembly-plugin</artifactId>
75+
<executions>
76+
<execution>
77+
<configuration>
78+
<archive>
79+
<manifest>
80+
<mainClass>com.iluwatar.vertical.slice.architecture.App</mainClass>
81+
</manifest>
82+
</archive>
83+
</configuration>
84+
</execution>
85+
</executions>
86+
</plugin>
87+
</plugins>
88+
</build>
89+
90+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
3+
*
4+
* The MIT License
5+
* Copyright © 2014-2022 Ilkka Seppälä
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package com.iluwatar.verticalslicearchitecture;
26+
27+
import org.springframework.boot.SpringApplication;
28+
import org.springframework.boot.autoconfigure.SpringBootApplication;
29+
30+
/**
31+
* main application.
32+
*/
33+
34+
@SpringBootApplication
35+
public class App {
36+
37+
public static void main(String[] args) {
38+
SpringApplication.run(App.class, args);
39+
}
40+
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
3+
*
4+
* The MIT License
5+
* Copyright © 2014-2022 Ilkka Seppälä
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package com.iluwatar.verticalslicearchitecture;
26+
27+
import com.iluwatar.verticalslicearchitecture.customer.Customer;
28+
import com.iluwatar.verticalslicearchitecture.customer.CustomerService;
29+
import com.iluwatar.verticalslicearchitecture.customer.CustomerView;
30+
import com.iluwatar.verticalslicearchitecture.order.OrderService;
31+
import com.iluwatar.verticalslicearchitecture.order.OrderView;
32+
import com.iluwatar.verticalslicearchitecture.product.Product;
33+
import com.iluwatar.verticalslicearchitecture.product.ProductService;
34+
import com.iluwatar.verticalslicearchitecture.product.ProductView;
35+
import lombok.AllArgsConstructor;
36+
import lombok.extern.slf4j.Slf4j;
37+
import org.springframework.boot.CommandLineRunner;
38+
import org.springframework.stereotype.Component;
39+
40+
/**
41+
* Seeding test data.
42+
*/
43+
44+
@Component
45+
@AllArgsConstructor
46+
@Slf4j
47+
public class Runner implements CommandLineRunner {
48+
49+
CustomerService customerService;
50+
OrderService orderService;
51+
ProductService productService;
52+
53+
@Override
54+
public void run(String... args) {
55+
initializeData();
56+
new OrderView(orderService).render(customerService.getCustomerById(1));
57+
new CustomerView(customerService).render();
58+
new ProductView(productService).render();
59+
}
60+
61+
/**
62+
* method for data seeds.
63+
*/
64+
65+
public void initializeData() {
66+
67+
Customer customer = Customer.builder().id(1).name("sugan0tech").email("[email protected]").build();
68+
customerService.createCustomer(customer);
69+
70+
Product oreo = Product.builder().id(1).price(2.00).name("Oreo").build();
71+
Product cone = Product.builder().id(3).price(1.15).name("Ice Cream Cone").build();
72+
Product apple = Product.builder().id(4).price(2.00).name("Apple").build();
73+
Product sandwich = Product.builder().id(2).price(6.00).name("Sandwich").build();
74+
productService.createProduct(oreo);
75+
productService.createProduct(cone);
76+
productService.createProduct(apple);
77+
productService.createProduct(sandwich);
78+
79+
orderService.createOrder(1, customer, oreo);
80+
orderService.createOrder(2, customer, sandwich);
81+
orderService.createOrder(3, customer, apple);
82+
}
83+
}

0 commit comments

Comments
 (0)