Last active
December 14, 2015 20:38
-
-
Save thara/5144869 to your computer and use it in GitHub Desktop.
A simple DCI sample with Mix-in in Dart.
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
import 'package:unittest/unittest.dart'; | |
import 'dart:async'; | |
main () { | |
test("DCI sample in Dart", () { | |
var checking = new Account(balance : 50); | |
var saving = new Account(balance : 45); | |
var savingContext = new SavingContext(checking: checking, saving: saving); | |
savingContext.save(30).then((sc){ | |
// Verify | |
expect(sc.checking.balance, equals(20)); | |
expect(sc.saving.balance, equals(75)); | |
}); | |
}); | |
} | |
/// Context | |
class SavingContext { | |
Account checking; | |
Account saving; | |
SavingContext({this.checking, this.saving}); | |
Future<SavingContext> save(int amount) { | |
var completer = new Completer<SavingContext>(); | |
var checkingRole = new TransferMoneySourceAccount()..apply(checking); | |
var savingRole = new TransferMoneySinkAcount()..apply(saving); | |
checkingRole.transferTo(savingRole, amount); | |
completer.complete(this); | |
return completer.future; | |
} | |
} | |
/// Base class for [Role] in DCI. | |
class Role<T> { | |
T _actor; | |
void apply(T actor) { | |
_actor = actor; | |
} | |
T get actor => _actor; | |
// identifier of role is same of actor | |
int get hashCode => _actor.hashCode; | |
bool operator ==(other) => _actor == other; | |
String toString() => _actor.toString(); | |
} | |
// A Enitty | |
class Account { | |
int _balance = 0; | |
Account({int balance}) : this._balance = balance { | |
if (this._balance == null) throw new ArgumentError("balance must not be null."); | |
} | |
int get balance => _balance; | |
void decrease(int amount) { | |
this._balance -= amount; | |
} | |
void increase(int amount) { | |
this._balance += amount; | |
} | |
} | |
// simple behaviors | |
abstract class MoneySource { | |
void withdraw(int amount); | |
} | |
abstract class MoneySink { | |
void deposit(int amount); | |
} | |
// more specified behaviors | |
abstract class TransferMoneySource extends MoneySource { | |
void transferTo(MoneySink recipient, int amount) { | |
withdraw(amount); | |
recipient.deposit(amount); | |
} | |
} | |
abstract class TransferMoneySink extends MoneySink { | |
void transferFrom(MoneySource source, int amount) { | |
source.withdraw(amount); | |
deposit(amount); | |
} | |
} | |
// roles | |
/// a role for account with [TransferMoneySource] behivior. | |
class TransferMoneySourceAccount extends TransferMoneySource with Role<Account> { | |
void withdraw(int amount) => actor.decrease(amount); | |
} | |
/// a role for account with [TransferMoneySink] behivior. | |
class TransferMoneySinkAcount extends TransferMoneySink with Role<Account> { | |
void deposit(int amount) => actor.increase(amount); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment