Skip to content

Instantly share code, notes, and snippets.

@thara
Last active December 14, 2015 20:38
Show Gist options
  • Save thara/5144869 to your computer and use it in GitHub Desktop.
Save thara/5144869 to your computer and use it in GitHub Desktop.
A simple DCI sample with Mix-in in Dart.
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