Skip to content

Instantly share code, notes, and snippets.

@yaakaito
Last active January 2, 2016 09:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yaakaito/8281742 to your computer and use it in GitHub Desktop.
Save yaakaito/8281742 to your computer and use it in GitHub Desktop.
型とか微妙になってるけど多分こんなん
var BankAccount = (function () {
function BankAccount(balance) {
this.balance = balance;
}
BankAccount.prototype.increase = function (money) {
var a = _.clone(this);
a.balance += money;
return a;
};
BankAccount.prototype.decrease = function (money) {
var a = _.clone(this);
a.balance -= money;
return a;
};
return BankAccount;
})();
var Sender = {
send: function (self, money, to) {
var newFrom = self.decrease(money);
var newTo = to.onReceived(money, newFrom);
return [newFrom, newTo];
}
};
var Receiver = {
onReceived: function (self, money, from) {
return self.increase(money);
}
};
var extendRole = function (self, role) {
var extended = {};
for (var m in role) {
extended[m] = function () {
var args = [];
for (var _i = 0; _i < (arguments.length - 0); _i++) {
args[_i] = arguments[_i + 0];
}
args.splice(0, 0, self);
return role[m].apply(role, args);
};
}
return extended;
};
var TransferContext;
(function (TransferContext) {
TransferContext.transfer = function (money, from, to) {
return extendRole(from, Sender).send(money, extendRole(to, Receiver));
};
})(TransferContext || (TransferContext = {}));
interface UnderscoreStatic {
clone(o: any): any;
}
declare var _: UnderscoreStatic;
class BankAccount {
constructor(
private balance: number
) { }
increase(money: number): BankAccount {
var a = _.clone(this);
a.balance += money;
return a;
}
decrease(money: number): BankAccount {
var a = _.clone(this);
a.balance -= money;
return a;
}
}
var Sender = {
send: (self: BankAccount, money: number, to: BankAccount): BankAccount[] => {
var newFrom = self.decrease(money);
var newTo = to.onReceived(money, newFrom);
return [newFrom, newTo];
}
}
var Receiver = {
onReceived: (self: BankAccount, money: number, from: BackAccount): BankAccount => self.increase(money)
}
var extendRole = (self: any, role: any): any => {
var extended = {};
for (var m in role) {
extended[m] = (...args: any[]): any => {
args.splice(0, 0, self);
return role[m].apply(role, args);
};
}
return extended;
}
module TransferContext {
export var transfer = (money: number, from: BankAccount, to: BackAccount) => {
return extendRole(from, Sender).send(money, extendRole(to, Receiver));
}
}
var a = new BankAccount(100);
> undefined
var b = new BankAccount(200);
> undefined
var c = TransferContext.transfer(50, a, b)
> undefined
c
> [
Object
balance: 50
decrease: function (money) {
increase: function (money) {
__proto__: Object
,
Object
balance: 250
decrease: function (money) {
increase: function (money) {
__proto__: Object
]
a
> BankAccount {balance: 100, increase: function, decrease: function}
b
> BankAccount {balance: 200, increase: function, decrease: function}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment