Last active
December 28, 2015 23:09
-
-
Save tlync/7576585 to your computer and use it in GitHub Desktop.
ドメイン層を特有のトランザクション管理の概念から独立させる為の Transparent context pattern (適当)
This file contains 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
// domain layer | |
trait Entity | |
trait Repo | |
case class Context[T](session: T) | |
trait TransparentContext[T] { | |
implicit def c2s(implicit ctx: Context[T]) = ctx.session | |
implicit def s2c(implicit session: T) = Context(session) | |
} | |
case class User(id: Int, name: String) extends Entity { | |
// ..snip.. | |
} | |
trait UserRepo[T] extends Repo { | |
def find(id: Int)(implicit ctx: Context[T]): Option[User] | |
} | |
// infra layer (for persistence abstraction) | |
import scalikejdbc._ | |
import SQLInterpolation._ | |
class ScalikeJdbcUserRepo extends UserRepo[DBSession] with TransparentContext[DBSession] { | |
private def rsToEntity(rs: WrappedResultSet): User = { | |
User(rs.int("id"), rs.string("name")) | |
} | |
def find(id: Int)(implicit ctx: Context[DBSession]): Option[User] = { | |
sql"select * from users where $id".map(rsToEntity).single().apply() | |
} | |
} | |
// app layer | |
object UserController extends Controller { | |
val someService = new AppService() // TODO: DI | |
def sampleLocalTx = Action { | |
val user = someService.doSomethingWithLocalTx() | |
user match { | |
case u: Some[User] => Ok(u.get.name) | |
case _ => NotFound | |
} | |
} | |
def sampleAutoCommit = Action { | |
val user = someService.doSomethingWithAutoCommit() | |
user match { | |
case u: Some[User] => Ok(u.get.name) | |
case _ => NotFound | |
} | |
} | |
} | |
class AppService extends TransparentContext[DBSession] { | |
import scalikejdbc._ | |
def doSomethingWithLocalTx() = { | |
DB localTx { implicit session => | |
val repo = new ScalikeJdbcUserRepo | |
repo.find(1) | |
// ... | |
} | |
} | |
def doSomethingWithAutoCommit() = { | |
DB autoCommit { implicit session => | |
val repo = new ScalikeJdbcUserRepo | |
repo.find(1) | |
// ... | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment