mirror of
https://github.com/CUBETIQ/hexagonal-architect-spring-boot
synced 2024-12-25 23:04:27 +07:00
Add basis domain logic and adapter for article impls
This commit is contained in:
parent
9355f913fd
commit
0e917f6a3d
@ -1,10 +1,33 @@
|
||||
package com.cubetiqs.hexagonal
|
||||
|
||||
import com.cubetiqs.hexagonal.infrastructure.adapter.cli.ArticleCli
|
||||
import com.cubetiqs.hexagonal.infrastructure.adapter.persistence.ArticleImMemoryDataAdapter
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.boot.CommandLineRunner
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
import org.springframework.boot.runApplication
|
||||
|
||||
@SpringBootApplication
|
||||
class HexagonalArchitectApplication
|
||||
class HexagonalArchitectApplication : CommandLineRunner {
|
||||
private val logger = LoggerFactory.getLogger(HexagonalArchitectApplication::class.java)
|
||||
|
||||
override fun run(vararg args: String?) {
|
||||
// create cli instance
|
||||
val cli = ArticleCli(ArticleImMemoryDataAdapter())
|
||||
|
||||
// create new article object via cli
|
||||
val article = cli.create(1L, "Article 1", "Description 1")
|
||||
logger.info("Article created: {}", article)
|
||||
|
||||
// retrieve article via cli
|
||||
val articleRetrieve = cli.retrieve(1L)
|
||||
logger.info("Article retrieved: {}", articleRetrieve)
|
||||
|
||||
// query articles via cli
|
||||
val articleQuery = cli.query(1L)
|
||||
logger.info("Query found articles: {}", articleQuery)
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
runApplication<HexagonalArchitectApplication>(*args)
|
||||
|
@ -0,0 +1,13 @@
|
||||
package com.cubetiqs.hexagonal.domain.article
|
||||
|
||||
import com.cubetiqs.hexagonal.domain.article.model.Article
|
||||
import com.cubetiqs.hexagonal.domain.article.port.ArticlePort
|
||||
import com.cubetiqs.hexagonal.domain.article.usecase.ArticleCreate
|
||||
|
||||
class ArticleCreateUseCase constructor(
|
||||
private val articlePort: ArticlePort,
|
||||
) {
|
||||
fun create(useCase: ArticleCreate): Article {
|
||||
return articlePort.create(useCase)
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.cubetiqs.hexagonal.domain.article
|
||||
|
||||
import com.cubetiqs.hexagonal.domain.article.model.Article
|
||||
import com.cubetiqs.hexagonal.domain.article.port.ArticlePort
|
||||
import com.cubetiqs.hexagonal.domain.article.usecase.ArticleQuery
|
||||
|
||||
class ArticleQueryUseCase constructor(
|
||||
private val articlePort: ArticlePort,
|
||||
) {
|
||||
fun query(useCase: ArticleQuery): Collection<Article> {
|
||||
return articlePort.query(useCase)
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.cubetiqs.hexagonal.domain.article
|
||||
|
||||
import com.cubetiqs.hexagonal.domain.article.model.Article
|
||||
import com.cubetiqs.hexagonal.domain.article.port.ArticlePort
|
||||
import com.cubetiqs.hexagonal.domain.article.usecase.ArticleRetrieve
|
||||
|
||||
class ArticleRetrieveUseCase constructor(
|
||||
private val articlePort: ArticlePort,
|
||||
) {
|
||||
fun retrieve(useCase: ArticleRetrieve): Article {
|
||||
return articlePort.retrieve(useCase.id)
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.cubetiqs.hexagonal.domain.article.model
|
||||
|
||||
open class Article (
|
||||
var id: Long? = null,
|
||||
var accountId: Long? = null,
|
||||
var title: String? = null,
|
||||
var body: String? = null,
|
||||
) {
|
||||
override fun toString(): String {
|
||||
return "Article(id=$id, accountId=$accountId, title=$title, body=$body)"
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.cubetiqs.hexagonal.domain.article.port
|
||||
|
||||
import com.cubetiqs.hexagonal.domain.article.model.Article
|
||||
import com.cubetiqs.hexagonal.domain.article.usecase.ArticleCreate
|
||||
import com.cubetiqs.hexagonal.domain.article.usecase.ArticleQuery
|
||||
|
||||
interface ArticlePort {
|
||||
fun create(article: ArticleCreate): Article
|
||||
fun retrieve(id: Long): Article
|
||||
fun query(query: ArticleQuery): Collection<Article>
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.cubetiqs.hexagonal.domain.article.usecase
|
||||
|
||||
open class ArticleCreate(
|
||||
var accountId: Long? = null,
|
||||
var title: String? = null,
|
||||
var body: String? = null,
|
||||
) {
|
||||
override fun toString(): String {
|
||||
return "ArticleCreate(accountId=$accountId, title=$title, body=$body)"
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.cubetiqs.hexagonal.domain.article.usecase
|
||||
|
||||
open class ArticleQuery(
|
||||
var accountId: Long,
|
||||
) {
|
||||
companion object {
|
||||
fun from(accountId: Long): ArticleQuery {
|
||||
return ArticleQuery(accountId)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "ArticleQuery(accountId=$accountId)"
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.cubetiqs.hexagonal.domain.article.usecase
|
||||
|
||||
open class ArticleRetrieve(
|
||||
var id: Long,
|
||||
) {
|
||||
companion object {
|
||||
fun from(id: Long): ArticleRetrieve {
|
||||
return ArticleRetrieve(id)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "ArticleRetrieve(id=$id)"
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.cubetiqs.hexagonal.infrastructure.adapter.cli
|
||||
|
||||
import com.cubetiqs.hexagonal.domain.article.model.Article
|
||||
import com.cubetiqs.hexagonal.domain.article.port.ArticlePort
|
||||
import com.cubetiqs.hexagonal.domain.article.usecase.ArticleCreate
|
||||
import com.cubetiqs.hexagonal.domain.article.usecase.ArticleQuery
|
||||
|
||||
class ArticleCli constructor(
|
||||
private val articlePort: ArticlePort,
|
||||
) {
|
||||
fun create(accountId: Long, title: String, body: String): Article {
|
||||
val article = ArticleCreate(accountId, title, body)
|
||||
return articlePort.create(article)
|
||||
}
|
||||
|
||||
fun retrieve(id: Long): Article {
|
||||
return articlePort.retrieve(id)
|
||||
}
|
||||
|
||||
fun query(accountId: Long): Collection<Article> {
|
||||
return articlePort.query(ArticleQuery.from(accountId))
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.cubetiqs.hexagonal.infrastructure.adapter.persistence
|
||||
|
||||
import com.cubetiqs.hexagonal.domain.article.model.Article
|
||||
import com.cubetiqs.hexagonal.domain.article.port.ArticlePort
|
||||
import com.cubetiqs.hexagonal.domain.article.usecase.ArticleCreate
|
||||
import com.cubetiqs.hexagonal.domain.article.usecase.ArticleQuery
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
class ArticleImMemoryDataAdapter : ArticlePort {
|
||||
companion object {
|
||||
private val articles = ConcurrentHashMap<Long, Article>()
|
||||
}
|
||||
|
||||
override fun create(article: ArticleCreate): Article {
|
||||
val id = (articles.size + 1).toLong()
|
||||
val entity = Article(id, article.accountId, article.title, article.body)
|
||||
articles[id] = entity
|
||||
return entity
|
||||
}
|
||||
|
||||
override fun retrieve(id: Long): Article {
|
||||
return articles[id] ?: throw IllegalArgumentException("Article not found")
|
||||
}
|
||||
|
||||
override fun query(query: ArticleQuery): Collection<Article> {
|
||||
return articles.values.filter {
|
||||
it.accountId == query.accountId
|
||||
}
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
|
2
src/main/resources/application.yaml
Normal file
2
src/main/resources/application.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
server:
|
||||
port: 8080
|
Loading…
Reference in New Issue
Block a user