Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
DDD + Scala        (@j5ik2o)
DDD   , Scala       , DSL   ,    ...DDD             2     (4,5,6 )@j5ik2o
agendaScala    DDD Scala DDD + Scala                        DSL JavaBeans
Scala
ScalaScala    .scala   .class    Java
Scala vs Java  Money            Scala                 }                                         public BigDecimal getAmoun...
Hello, World!!object HelloWorld{    def main(args: Array[String]):Unit = {        println(“Hello, World!!”)    }}
valscala> val name = "Junichi Kato"name: java.lang.String = Junichi Katoscala> name = "JUNICHI KATO"<console>:6: error: re...
varscala> var name = "Junichi Kato"name: java.lang.String = Junichi Katoscala> name = "JUNICHI KATO"name: java.lang.String...
typescala> val name = "Junichi Kato"name: java.lang.String = Junichi Katoscala> val name:String = "Junichi Kato"name: Stri...
methoddef add(a:Int, b:Int):Int = {    return a + b}def add(a:Int, b:Int):Int = a + bdef add(a:Int, b:Int) = a + bhoge.add...
if & forifval a = 10val ret = if (a % 2 == 0) true else falseval ret = if (a % 2 == 0) { println(“     ”); true }else { pr...
classclass PersonName(fn: String, ln: String){    require(fn.length > 0) //           IAE    require(ln.length > 0) //    ...
classclass PersonName(val firstName:String, vallastName: String){require(firstName.length > 0)require(lastName.length > 0)de...
classval pn = new PersonName(“Junichi”, “Kato”)println(pn.fullName)val pn2 = new PersonName(“”, “Kato”) / IAE             ...
objectobject EmployeeDao {    val DEFAULT_NAME = ...    def findAll = ...}val result = EmployeeDao.findAllval defaultName = ...
{               ,                }class Money(val amount:BigDecimal, val currency: Currency) ...object Money {    val JPY ...
matchdef numberMatch(n:Int) = n match {    case 1 => “one”    case 2 | 3 => “t wo or three”    case _ => “other”}println(n...
matchval pattern = """([a-z]+)""".r               case Array(1,2,3) => println(“def matchTest(word: Any) = word           ...
(a:Int) => a * aval square: (Int) => Int = (a:Int) => a * aval square = (a:Int) => a * aval result = square(2) / 4        ...
object MyMath {  def add(a:Int, b:Int) = a + b}val f1 = MyMath.add _val f2: (Int,Int) => Int = MyMath.add
Collectionval il1 = List(1,2,3)val il2 = list :+ 4 / 1,2,3,4                     /val im1 = Map(1 -> “ 2 -> “b”, 3 -> “c”)...
Collectionval numbers = List(1,2,3,45)numbers.foreach((n:Int) => println(n) ) / (1)                                       ...
Collectionval evens = numbers.filter(_ % 2 == 0) //numbersval list = List(1,2,3).map(_ * 2) / 2,4,6                        ...
CollectionRange         ( (Seq)                     )val range = 1 to 10; range.foreach(println)for(i <- 1 to 10 by 2) pri...
traittrait Greeting { def greet:Unit }class JapaneseGreeting extends Greeting { def greet = println(“            ”)}class ...
DDD + Scala
Domain Object &   Lifecycle
Entitytrait Entity {    val id: String //               OK    def equals(other: Any) = other match {        case that: Ent...
Entityclass Employee(val id: String, val name:String)extends Entityval kato1 = new Employee(“1”, “Junichi Kato”)val kato2 ...
Entity with Factoryclass Employee         object Employee{(val id:String,         def apply(id:String,                    ...
Entity with Factoryval kato = Employee(“KATO”,Department(“DEV”))
Value Object with Factoryclass Money                         override def toString =                                   "Mo...
Value Object with FactoryVOassert(Money(100, Money.JPY) == Money(100, Money.JPY))assert(Money(100, Money.JPY) != Money(105...
Value Object(case class)case class Money(amount: BigDecimal, currency:Currency)     apply, unapply                        ...
ValueObject Buildercase class PersonName(firstName: String, lastName:String)class PersonNameBuilder extendsValueObjectBuidl...
Serviceobject TransferSer vice { def transfer(money: Money,from:BankAccount, to:BankAccount) =    to.push(from.pull(money)...
Aggregateclass Employee(val id:String, var name:String, var dept:Department) extends Entity  Employee                     ...
Aggregate          Department (               )class Employee(val id:String, var name:String, var dept:Department) extends...
Aggregate(Cloneable)@cloneable                                          }class Department(val id: String, var name:       ...
Aggregate(clone)clone     Mix-in@cloneabletrait EntityCloneable[T <: Entity] {    this: Entity =>    override def clone: T...
Aggregate(clone)class Employee (val id: String, var name: String)  extends Entity withEntityCloneable[Employee]val emp = E...
Aggregate(Factory)                   Factoryobject Department {    def apply(dept: Department) =     new Department(dept, ...
Repositorytrait EntityResolver[T <: Entity] extends Iterable[T]{    def resolve(id: String): T    def apply(id: String) = ...
Repositoryclass EmployeeResolver extends   val er = new EmployeeResolverEntityResolver[Employee] {                        ...
Repositorytrait Repository[T <: Entity] extendsEntityResolver[T] {    def store(entity: T) def update(identifier: Identifier...
Repositoryclass EmployeeRepository           / resolve, iterator ...                                    /extendsRepository...
(         )=id(4a74c322-08ab-450b-b674-793e1d7f399a) = classDepartment {    package = dept    fields {        name = java.l...
package dept;public class Department {    private java.lang.String name;    public void setName(java.lang.String name){   ...
(.ftl)<#if classMeta.getPackageName()??>            <#assign getter = "is"/>package ${classMeta.getPackageName()};        ...
codegen -hcodegen -c sample.config -t template -e exportcodegen -c [4a74c322-08ab-450b-b674-793e1d7f399a]@sample.config -tte...
ClassMeta              FieldMeta          CodeGenSer viceFactory          ClassMetaRepository
ClassMeta Entitypackage codegen.domainclass ClassMeta(@BeanProperty val identifier: Identifier, @BeanProperty val name:Strin...
ClassMeta Objectobject ClassMeta { def apply(identifier: Identifier, name: String, packageName: Option[String],fieldMetas: Li...
FieldMeta VO & VO Factorycase class FieldMeta(@BeanProperty name:String, @BeanProperty typeName: String)
ClassMetaRepositorypackage codegen.domainclass ClassMetaRepository(configSource: BufferedSource)extends EntityResolver[Clas...
CodeGenSer vicepackage codegen.domain                                   val exportClassDir =                              ...
Applicationpackage codegen.application                               getExportDir(parameters),object Application extends L...
Application private def generate(configFile: File,                   CodeGenSer vice.generate(exportDir, templateDir,      ...
ddd+scala
Upcoming SlideShare
Loading in …5
×

14

Share

Download to read offline

ddd+scala

Download to read offline

DDDをScalaでどうやって実装していくかという話題。前半はScalaの適当な紹介と、その後にDDDのビルディングブロックをScalaコード上に反映するにはどうするかって話です。残りのサンプルは時間がなくて説明していません。すみません。

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

ddd+scala

  1. 1. DDD + Scala (@j5ik2o)
  2. 2. DDD , Scala , DSL , ...DDD 2 (4,5,6 )@j5ik2o
  3. 3. agendaScala DDD Scala DDD + Scala DSL JavaBeans
  4. 4. Scala
  5. 5. ScalaScala .scala .class Java
  6. 6. Scala vs Java Money Scala } public BigDecimal getAmount() {case class Money(amount :BigDecimal, currency : Currency) return amount; Money Java }public class Money { public Currency getCurrency() { private final BigDecimal amount; return currency; } private final Currency currency; public Money(BigDecimal amnt, / equals, hashCode /Currency creny) { (ry amount = amt; } currency = creny;
  7. 7. Hello, World!!object HelloWorld{ def main(args: Array[String]):Unit = { println(“Hello, World!!”) }}
  8. 8. valscala> val name = "Junichi Kato"name: java.lang.String = Junichi Katoscala> name = "JUNICHI KATO"<console>:6: error: reassignment to val name = "JUNICHI KATO"
  9. 9. varscala> var name = "Junichi Kato"name: java.lang.String = Junichi Katoscala> name = "JUNICHI KATO"name: java.lang.String = JUNICHI KATO
  10. 10. typescala> val name = "Junichi Kato"name: java.lang.String = Junichi Katoscala> val name:String = "Junichi Kato"name: String = Junichi Katoscala> val num:Number = 100Lnum: java.lang.Number = 100
  11. 11. methoddef add(a:Int, b:Int):Int = { return a + b}def add(a:Int, b:Int):Int = a + bdef add(a:Int, b:Int) = a + bhoge.add(1, 2) / 3 /
  12. 12. if & forifval a = 10val ret = if (a % 2 == 0) true else falseval ret = if (a % 2 == 0) { println(“ ”); true }else { println(“ ”); false }def isEven(n: Int) = if (n % 2 == 0) true else falseforfor(i <- 1 to 3) println(i) / 1,2,3 /for(i <- Array(1,2,3)) println(i) / 1,2,3 /val numbers = for(i <- 1 to 10) yield i
  13. 13. classclass PersonName(fn: String, ln: String){ require(fn.length > 0) // IAE require(ln.length > 0) // IAE val firstName = fn val lastName = ln def fullName = “%s, %s”.format(firstName, lastName)}
  14. 14. classclass PersonName(val firstName:String, vallastName: String){require(firstName.length > 0)require(lastName.length > 0)def fullName = “%s, %s”.format(firstName,lastName)
  15. 15. classval pn = new PersonName(“Junichi”, “Kato”)println(pn.fullName)val pn2 = new PersonName(“”, “Kato”) / IAE /
  16. 16. objectobject EmployeeDao { val DEFAULT_NAME = ... def findAll = ...}val result = EmployeeDao.findAllval defaultName = EmployeeDao.DEFAULT_NAME
  17. 17. { , }class Money(val amount:BigDecimal, val currency: Currency) ...object Money { val JPY = Currency.getInstance(“JPY”) def apply(amount: BigDecimal, currency: Currency) = newMoney(amount, currency)}val money:Money = Money(100, Money. JPY)/ val money:Money = Money.apply(100, Money.JPY) /
  18. 18. matchdef numberMatch(n:Int) = n match { case 1 => “one” case 2 | 3 => “t wo or three” case _ => “other”}println(numberMatch(1)) / one /println(numberMatch(2)) / t wo or three /println(numberMatch(3)) / t wo or three /println(numberMatch(4)) / other /
  19. 19. matchval pattern = """([a-z]+)""".r case Array(1,2,3) => println(“def matchTest(word: Any) = word 1,2,3 ”)match { case _ => throw new case “ABC” => println(“ABC ”) IllegalArgumentException case pattern(s) => println(" } = "+s) matchTest(“ABC”) / ABC / case s: String => println(“ matchTest("aaaa") // = = (%s)”.format(s)) (aaaa) case n: Int if (n >= 2) => println(“2 matchTest(10) / 2 / ”) matchTest(Array(1,2,3)) // 1,2,3
  20. 20. (a:Int) => a * aval square: (Int) => Int = (a:Int) => a * aval square = (a:Int) => a * aval result = square(2) / 4 /
  21. 21. object MyMath { def add(a:Int, b:Int) = a + b}val f1 = MyMath.add _val f2: (Int,Int) => Int = MyMath.add
  22. 22. Collectionval il1 = List(1,2,3)val il2 = list :+ 4 / 1,2,3,4 /val im1 = Map(1 -> “ 2 -> “b”, 3 -> “c”) a”,val im2 = m1 + (4 -> “d”) / 1 -> “ 2 -> “b”, 3 -> “c”, 4 -> “d” / a”,val ml = ListBuffer(1,2,3)ml += 4val mm = collection.mutalble.Map(1 -> “ 2 -> “b”, 3 -> “c”) a”,mm += (4 -> “d”)
  23. 23. Collectionval numbers = List(1,2,3,45)numbers.foreach((n:Int) => println(n) ) / (1) /numbers.foreach(n => println(n)) / (2) /numbers.foreach(_ => println(_)) / (3) /numbers.foreach(println(_)) / (4) /numbers.foreach(println) / (5) /varl map = Map(1 -> “ 2 -> “b”) a”,map.foreach(entry => println(“key = %s, value =%s”.format(entry._1,entry._2)))
  24. 24. Collectionval evens = numbers.filter(_ % 2 == 0) //numbersval list = List(1,2,3).map(_ * 2) / 2,4,6 /
  25. 25. CollectionRange ( (Seq) )val range = 1 to 10; range.foreach(println)for(i <- 1 to 10 by 2) println(i) / 1 3 5 7 9 /6 FizzBuzz(1 to 100).map{ case n if (n % 15 == 0) => “FizzBuzz” case n if (n % 3 == 0) => “Fizz” case n if (n % 5 == 0) => “Buzz” case n => n}.foreach(println)
  26. 26. traittrait Greeting { def greet:Unit }class JapaneseGreeting extends Greeting { def greet = println(“ ”)}class EnglishGreeting extends Greeting { def greet = println(“Hello”)}mix-intrait Logging { def log(msg: String) = println(msg) }class Employee(name:String) extends AbstractEmployee withLogging { log(“name = “+name)}
  27. 27. DDD + Scala
  28. 28. Domain Object & Lifecycle
  29. 29. Entitytrait Entity { val id: String // OK def equals(other: Any) = other match { case that: Entity => id == that.id case _ => false } def hashCode = id.hashCode}
  30. 30. Entityclass Employee(val id: String, val name:String)extends Entityval kato1 = new Employee(“1”, “Junichi Kato”)val kato2 = new Employee(“2”, “Junichi Kato”)val kato3 = new Employee(“3”, “JUNICHI KATO”)assert(kato1 != kato2)assert(kato1 == kato3)
  31. 31. Entity with Factoryclass Employee object Employee{(val id:String, def apply(id:String, name:String,var name:String, dept:Department) = newvar dept:Department) Employee(id, name, dept)extends Entity }
  32. 32. Entity with Factoryval kato = Employee(“KATO”,Department(“DEV”))
  33. 33. Value Object with Factoryclass Money override def toString = "Money(%s, %s)".format(amount,(val amount: BigDecimal, currency)val currency: Currency){ } override def equals(that: Any): object Money {Boolean = that match { def apply(amount: BigDecimal, case other: Money => amount == currency: Currency) = newother.amount && currency == Money(amount, currency)other.currency def unapply(money: Money) = case _ => false Some(money.amount, } money.currency) override def hashCode = }amount.hashCode +currency.hashCode
  34. 34. Value Object with FactoryVOassert(Money(100, Money.JPY) == Money(100, Money.JPY))assert(Money(100, Money.JPY) != Money(105, Money.JPY))assert(Money(100, Money.JPY) != Money(100, Money.USD)) unapplyval Money(amt, cry) = money1_100yenprintln(“ amount = %s, currency = %s”.format(amt, cry))money1_100yen match { / match /case Money(amt, cry) => println(“ amount = %s, currency = %s”.format(amt,cry))case _ => ()}
  35. 35. Value Object(case class)case class Money(amount: BigDecimal, currency:Currency) apply, unapply val toString, equals, hashCodeVO case class Money(amount:BigDecimal, currency: Currency) extends ValueObject
  36. 36. ValueObject Buildercase class PersonName(firstName: String, lastName:String)class PersonNameBuilder extendsValueObjectBuidler[PersonName, PersonNameBuilder] { ... } VOval personName1 = newPersonNameBuilder().withFirstName("Junichi").withLastName("Kato").buildval personName2 = newPersonNameBuilder().withLastName(lastName.toUpperCase).build(personName1)
  37. 37. Serviceobject TransferSer vice { def transfer(money: Money,from:BankAccount, to:BankAccount) = to.push(from.pull(money))}TransferService.transfer(Money(1000,JPY),BankAccount(“012345”),BankAccount(“543210”))
  38. 38. Aggregateclass Employee(val id:String, var name:String, var dept:Department) extends Entity Employee id, name, dept
  39. 39. Aggregate Department ( )class Employee(val id:String, var name:String, var dept:Department) extends Entityclass Department(val id: String, var name: String) extends Entityval dept = Department(“1:1”, “DEV)val emp = Employee(“1”, “KATO”, dept) / (1) /dept.name = “SALES” / (1) /val dept = emp.dept / (2) /dept.name = “SALES” / (2) /
  40. 40. Aggregate(Cloneable)@cloneable }class Department(val id: String, var name: override def clone = { / (4) /String) extends Entity { val result = override def clone = super.clone.asInstanceOf[Employee]super.clone.asInstanceOf[Department] result.dpt = dpt.clone} }@cloneable }class Employee(val id:String, var val dept = Department(“1:1”, “DEV”)name:String, _dpt: Department) extendsEntity { val emp = Employee(“1”, “KATO”, dept) / (1) / private var dpt = _dpt.clone / (1) / dept.name = “SALES” def dept = dpt.clone / getDept / (2) val dept = emp.dept / (2) / def dept_= (value: Deaprtment) { // dept.name = “SALES”setDept emp.dept = Department(“1:1”, “SALES”) / (3) / dpt = value.clone / (3) / val cloneEmp = emp.clone / (4) /
  41. 41. Aggregate(clone)clone Mix-in@cloneabletrait EntityCloneable[T <: Entity] { this: Entity => override def clone: T = super.clone.asInstanceOf[T]}
  42. 42. Aggregate(clone)class Employee (val id: String, var name: String) extends Entity withEntityCloneable[Employee]val emp = Employee(“1”, “Kato”)val cloneEmp = emp.clone
  43. 43. Aggregate(Factory) Factoryobject Department { def apply(dept: Department) = new Department(dept, dept.name)}object Employee { def apply(emp: Employee) = new Employee(emp.id, emp.name, Department(emp.dept))}val emp = Employee(“1”, “KATO”, Department(“1:1”, “DEV”))val cloneEmp = Employee(emp)
  44. 44. Repositorytrait EntityResolver[T <: Entity] extends Iterable[T]{ def resolve(id: String): T def apply(id: String) = resolve(id) def contains(id: String): Boolean = exists(_.id == id) def contains(entity: T): Boolean = exists(_ == entity)}
  45. 45. Repositoryclass EmployeeResolver extends val er = new EmployeeResolverEntityResolver[Employee] { val employee = er.resolve(id) private val employees = val employee = er(id) / er.apply /Map(“1” -> Employee(“1”, -> resolve“KATO”, Department(“1:1”,“DEV”))) val employee = er.contains(id) def resolve(id: String) = val exists = er.exists(_.name ==employees(id) “KATO”) def iterator = val employees =employees.map(e => er.filter(_.name.startWith(“K”))e._2.clone).iterator er.foreach(println)}
  46. 46. Repositorytrait Repository[T <: Entity] extendsEntityResolver[T] { def store(entity: T) def update(identifier: Identifier, entity:T) =store(entity) def delete(identity: Identifier) def delete(entity: T)}
  47. 47. Repositoryclass EmployeeRepository / resolve, iterator ... /extendsRepository[Employee] { } private val employees = val er = newcollection.mutalble.Map.emp EmployeeRepositoryty[String, Employee] val emp = Employee(id, def store(emp: Employee) = “KATO”, Department(“DEV))employees += (emp.id -> emp) er.store(emp) def delete(id: String) = er(id) = empemployee -= emp.id er.delete(id) def delete(emp: Employee) =delete(emp.id) er.delete(emp)
  48. 48. ( )=id(4a74c322-08ab-450b-b674-793e1d7f399a) = classDepartment { package = dept fields { name = java.lang.String }}
  49. 49. package dept;public class Department { private java.lang.String name; public void setName(java.lang.String name){ this.name = name; } public java.lang.String getName(){ return name; }}
  50. 50. (.ftl)<#if classMeta.getPackageName()??> <#assign getter = "is"/>package ${classMeta.getPackageName()}; <#elseif f.getTypeName() == "java.lang.Boolean"></#if> <#assign getter = "is"/>public class ${classMeta.getName()} { <#else><#list classMeta.getFieldMetas() as f> <#assign getter = "get"/> private ${f.getTypeName()} ${f.getName()}; </#if> public void set${f.getName()?cap_first} public ${f.getTypeName()} ${getter}$(${f.getTypeName()} ${f.getName()}){ {f.getName()?cap_first}(){ this.${f.getName()} = $ return ${f.getName()};{f.getName()}; } } </#list> }<#if f.getTypeName() == "boolean">
  51. 51. codegen -hcodegen -c sample.config -t template -e exportcodegen -c [4a74c322-08ab-450b-b674-793e1d7f399a]@sample.config -ttemplate -e export
  52. 52. ClassMeta FieldMeta CodeGenSer viceFactory ClassMetaRepository
  53. 53. ClassMeta Entitypackage codegen.domainclass ClassMeta(@BeanProperty val identifier: Identifier, @BeanProperty val name:String, val packageName: Option[String], val fieldMetas: List[FieldMeta])extends Entity { override def toString: String = "ClassMeta(%s, %s, %s,%s)".format(identifier, name, packageName, fieldMetas) def getPackageName(): String = if (packageName.isEmpty) null elsepackageName.get def getFieldMetas(): java.util.List[FieldMeta] = fieldMetas.asJava}
  54. 54. ClassMeta Objectobject ClassMeta { def apply(identifier: Identifier, name: String, packageName: Option[String],fieldMetas: List[FieldMeta]) = new ClassMeta(identifier, name, packageName, fieldMetas)def apply(name: String, packageName: Option[String], fieldMetas:List[FieldMeta]): ClassMeta = apply(Identifier(), name, packageName, fieldMetas) def apply(classMeta: ClassMeta): ClassMeta = apply(classMeta.identifier, classMeta.name, classMeta.packageName,classMeta.fieldMetas) def unapply(classMeta: ClassMeta) = Some(classMeta.identifier, classMeta.name, classMeta.packageName,classMeta.fieldMetas)}
  55. 55. FieldMeta VO & VO Factorycase class FieldMeta(@BeanProperty name:String, @BeanProperty typeName: String)
  56. 56. ClassMetaRepositorypackage codegen.domainclass ClassMetaRepository(configSource: BufferedSource)extends EntityResolver[ClassMeta] { private val classMetas = newModelParser().parse(configSource) private val classMetaMap = classMetas.map(classMeta =>(classMeta.identifier, classMeta)).toMap def iterator: Iterator[ClassMeta] =classMetaMap.map(classMeta => ClassMeta(_._2)).iterator def resolve(identifier: Identifier): ClassMeta =ClassMeta(classMetaMap(identifier))}
  57. 57. CodeGenSer vicepackage codegen.domain val exportClassDir = getExportClassDir(classMeta)object CodeGenSer vice{ exportClassDir.mkdirs def generate(exportDir: File, templateDir: File,classMetas: List[ClassMeta], using(new FileWriter(new File(exportClassDir, classMeta.name + ".java"))) { beginHandler: Option[(ClassMeta) => Unit], fileWriter => endHandler: Option[(ClassMeta) => Unit] ) = { template.process(rootMap.asJava, val configuration = new Configuration fileWriter); fileWriter.flush();configuration.setDirectoryForTemplateLoading(templateDir) } / using / val template = / ... /configuration.getTemplate("java.ftl") } / foreach / classMetas.foreach { } classMeta => / ... / / ... / } val rootMap = Map("classMeta" ->classMeta)
  58. 58. Applicationpackage codegen.application getExportDir(parameters),object Application extends Logging { getIdList(parameters)) def main(args: Array[String]) { } try { val commandLine = new } catch {CommandLineParser().parse(args.mkString(" ")) case e: CommandLineParseException => commandLine match { println(" case Help() => println("""-c ")[[id1,id2]@]file.config [-t templateDir][-e exportDir]""") } case parameters: Parameters => }generate(getConfigFile(parameters), getTemplateDir(parameters), }
  59. 59. Application private def generate(configFile: File, CodeGenSer vice.generate(exportDir, templateDir, targets, templateDir: File, Some({ exportDir: File, c => info("id(%s) : class %s ids: List[String]) { ".format(c.identifier.value, c.name)) info("= %s, = %s, }), = %s".format(configFile, templateDir, Some({exportDir)) c => info("id(%s) : class %s val repos = new ".format(c.identifier.value, c.name))ClassMetaRepository(Source.fromFile(configFile)) })) val targets = ids match { info(" ") case Nil => repos.toList case xs => xs.map { } catch { e => repos.resolve(Identifier(e)) case e: Exception => error(" } ", e) } } try { }
  • reoring

    Nov. 8, 2015
  • wakamen-slideshare

    Jun. 10, 2015
  • isseyurano

    Mar. 2, 2015
  • sigma5621

    Dec. 1, 2014
  • tyorosan

    Oct. 21, 2014
  • KosukeIida

    Sep. 3, 2014
  • KentoSugimoto

    Mar. 15, 2014
  • ryuichi-ishitsuka

    Jan. 16, 2014
  • 1parita

    Jun. 7, 2013
  • KazuhiroTominaga

    Oct. 12, 2011
  • choplin

    Apr. 26, 2011
  • matsumana0101

    Apr. 10, 2011
  • restartr

    Apr. 10, 2011
  • tlync

    Apr. 10, 2011

DDDをScalaでどうやって実装していくかという話題。前半はScalaの適当な紹介と、その後にDDDのビルディングブロックをScalaコード上に反映するにはどうするかって話です。残りのサンプルは時間がなくて説明していません。すみません。

Views

Total views

4,991

On Slideshare

0

From embeds

0

Number of embeds

73

Actions

Downloads

34

Shares

0

Comments

0

Likes

14

×