Advertisement
Guest User

Untitled

a guest
Jan 19th, 2017
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.07 KB | None | 0 0
  1. module ContextAccessor
  2. def context
  3. Thread.current[:context]
  4. end
  5.  
  6. def context=(ctx)
  7. Thread.current[:context] = ctx
  8. end
  9.  
  10. def execute_in_context
  11. original_context = self.context
  12. self.context = self
  13. yield
  14. self.context = original_context
  15. end
  16. end
  17.  
  18.  
  19. class Account
  20. attr_reader :account_id, :balance
  21.  
  22. def self.find(id)
  23. (@@accounts ||= {})[id] ||= new(id)
  24. end
  25.  
  26. def initialize(account_id)
  27. @account_id = account_id
  28. @balance = 1000
  29. end
  30.  
  31. def update_log(message, time, amount)
  32. puts "#{@account_id} :: #{time.strftime('%e %b %Y %H:%M:%S%p')} : #{message} #{balance}"
  33. end
  34. end
  35.  
  36.  
  37. module MoneySource
  38. def decrease_balance(amount)
  39. @balance -= amount
  40. end
  41. end
  42.  
  43. module MoneySink
  44. def increase_balance(amount)
  45. @balance += amount
  46. end
  47. end
  48.  
  49. module TransferMoneySource
  50. include MoneySource, ContextAccessor
  51.  
  52. def transfer_out
  53. raise "Insufficient funds" if balance < context.amount
  54. self.decrease_balance context.amount
  55. self.update_log "-#{context.amount}", Time.now, context.amount
  56. end
  57. end
  58.  
  59. module TransferMoneySink
  60. include MoneySink, ContextAccessor
  61.  
  62. def transfer_in
  63. self.increase_balance context.amount
  64. self.update_log "+#{context.amount}", Time.now, context.amount
  65. end
  66. end
  67.  
  68.  
  69. class TransferMoneyContext
  70. attr_reader :source_account, :destination_account, :amount
  71. include ContextAccessor
  72.  
  73. def self.execute(amt, source_account_id, destination_account_id)
  74. TransferMoneyContext.new(amt, source_account_id, destination_account_id).execute
  75. end
  76.  
  77. def initialize(amt, source_account_id, destination_account_id)
  78. @source_account = Account.find(source_account_id)
  79. @source_account.extend TransferMoneySource
  80.  
  81. @destination_account = Account.find(destination_account_id)
  82. @destination_account.extend TransferMoneySink
  83. @amount = amt
  84. end
  85.  
  86. def execute
  87. execute_in_context do
  88. begin
  89. source_account.transfer_out
  90. destination_account.transfer_in
  91. end
  92. end
  93. end
  94.  
  95. end
  96.  
  97.  
  98. TransferMoneyContext.execute(500, :savings, :checking)
  99. TransferMoneyContext.execute(100, :savings, :checking)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement