Skip to content

Instantly share code, notes, and snippets.

View j5ik2o's full-sized avatar

Junichi Kato j5ik2o

View GitHub Profile
trait BTree {
fn size(&self) -> i32;
fn sum(&self) -> i64;
fn min(&self) -> i64;
fn max(&self) -> i64;
fn find(&self, value: i64) -> Option<i64>;
}
enum Node {
Leaf {
// 絵の具を表すオブジェクト(副作用が伴う可変オブジェクト)
public class Paint {
private int volume;
private PigmentColor pigmentColor;
// getter, setter 省略
public Paint(PigmentColor pigmentColor, int volume) {
this.volume = volume;
this.pigmentColor = pigmentColor;
}
case class Money(amount: BigDecimal,
currency: Currency) {
def plus(other: Money): Money = {
require(currency == other.currency)
new Money(amount = amount.add(other.amount), currency)
}
}
case class UserAcount(id: Long, name: String, groupId: Long) {
// ...
def groupName(groupRepository: GroupRepository): Task[GroupName] = groupRepository.resolveBy(groupId).map(_.name)
}
package domain
trait Money {
def plus(other: Money): Money
def minus(other: Money): Money
// ...
}
@j5ik2o
j5ik2o / q1.md
Last active September 7, 2018 17:20

型パラメータが高階型の場合のDIについて

トレイト: UserAccountRepository[M[_]] https://github.com/j5ik2o/scala-ddd-base/blob/master/example/src/main/scala/com/github/j5ik2o/dddbase/example/repository/UserAccountRepository.scala

実装: UserAccountRepositoryBySkinny https://github.com/j5ik2o/scala-ddd-base/blob/master/example/src/main/scala/com/github/j5ik2o/dddbase/example/repository/skinny/UserAccountRepositoryBySkinny.scala

があったとして、以下のようなDIをさせたいのですが、

class ApiServer extends HttpApp {
protected val design: Design = bind[Design] // ApiServerの外部で定義されているDesginを参照したい
.bind[AtomicReference[ActorSystem]]
.toInstance(systemReference)
.bind[ActorSystem]
.toInstanceProvider[AtomicReference[ActorSystem]](_.get)
// snip
package point
import akka.actor.{Actor, ActorRef, ActorSystem, Props}
import point.MainActor.Start
import point.Point.{Distance, DistanceResult}
import scala.concurrent.Await
import scala.concurrent.duration._
object MainActor {
case class Room(id: Long, members: Seq[Member])
// このロジックはRoomが持つべき振る舞いだった場合(ドメインロジックがドメインオブジェクトの外側にある状態)
room.copy(members = room.members :+ newMember)
// ほんとは、こうしたらよいのでは
case class Room(id: Long, members: Seq[Member]) {
def addMember(value: Member): Room =
copy(members = this.members :+ value)
}
room.addMember(newMember)
package app
import cats.free._
import cats._
class DDD[ID, E] {
def resolveBy(id: ID): Free[RepositoryDSL, Option[E]] = Free.liftF(ResolveBy(id))
def store(id: ID, entity: E): Free[RepositoryDSL, Unit] = Free.liftF(Store(id, entity))