1 package scaladci 2 package examples.MoneyTransfer 3 import scala.language.reflectiveCalls 4 5 case class LedgerEntry(message: String, amount: Int) 6 7 case class Account(account: String, initialLedgers: List[LedgerEntry]) { 8 private val ledgers = new { 9 var ledgerList = initialLedgers 10 def addEntry(message: String, amount: Int) { ledgerList = ledgerList :+ new LedgerEntry(message, amount) } 11 def getBalance = ledgerList.foldLeft(0)(_ + _.amount) 12 } 13 14 def balance = ledgers.getBalance 15 def increaseBalance(amount: Int) { ledgers.addEntry("depositing", amount) } 16 def decreaseBalance(amount: Int) { ledgers.addEntry("withdrawing", -amount) } 17 } 18 19 class MoneyTransfer(src: Account, dest: Account, amount: Int) extends Context { 20 private val source = src.as[Source] 21 private val destination = dest.as[Destination] 22 23 def transfer() { 24 source.transfer 25 } 26 27 private trait Source {self: Account => 28 def withdraw() { 29 decreaseBalance(amount) 30 } 31 def transfer() { 32 println("Source balance is: " + balance) 33 println("Destination balance is: " + destination.balance) 34 destination.deposit() 35 withdraw() 36 println("Source balance is now: " + balance) 37 println("Destination balance is now: " + destination.balance) 38 } 39 } 40 41 private trait Destination {self: Account => 42 def deposit() { 43 increaseBalance(amount) 44 } 45 } 46 } 47 48 object MoneyTransferMarvinTest extends App { 49 val source = Account("salary", List(LedgerEntry("start", 0), LedgerEntry("first deposit", 1000))) 50 val destination = Account("budget", List()) 51 val context = new MoneyTransfer(source, destination, 245) 52 context.transfer() 53 } 54 55 /* prints: 56 57 Source balance is: 1000 58 Destination balance is: 0 59 Source balance is now: 755 60 Destination balance is now: 245 61 62 */