package contexts;
typedef SourceAccountInterface =
{
function Withdraw(amount : Float) : Void;
}
typedef DestinationAccountInterface =
{
function Deposit(amount : Float) : Void;
}
typedef MoneyTransferRoles =
{
private var sourceAccount : SourceAccount;
private var destinationAccount : DestinationAccount;
private var amount : Amount;
}
@:build(Dci.context())
class MoneyTransfer
{
private var sourceAccount : SourceAccount;
private var destinationAccount : DestinationAccount;
private var amount : Amount;
public function new(source, destination, amount)
{
bindRoles(source, destination, amount);
}
private function bindRoles(source, destination, amt)
{
sourceAccount = new SourceAccount(source);
destinationAccount = new DestinationAccount(destination);
amount = new Amount(amt);
}
// Interaction
public function Execute()
{
sourceAccount.Transfer();
}
}
@:build(Dci.role(MoneyTransfer))
private abstract Amount(Float) from Float to Float
{
public inline function new(amount)
{
this = amount;
}
}
@:build(Dci.role(MoneyTransfer))
private abstract SourceAccount(SourceAccountInterface)
{
public inline function new(account)
{
this = account;
}
public function Transfer()
{
this.Withdraw(context.amount);
context.destinationAccount.Deposit(context.amount);
}
}
@:build(Dci.role(MoneyTransfer))
private abstract DestinationAccount(DestinationAccountInterface)
{
public inline function new(account)
{
this = account;
}
public function Deposit(amount : Float)
{
this.Deposit(amount);
}
}