Skip to content

Instantly share code, notes, and snippets.

@lwoodson
Created November 16, 2012 23:17
Show Gist options
  • Save lwoodson/4091809 to your computer and use it in GitHub Desktop.
Save lwoodson/4091809 to your computer and use it in GitHub Desktop.
Supply chain DCI
class ManufacturingContext
def initialize(manufacturer, payor, item, quantity)
@manufacturer = manufacturer
@payor = payor
@item = item
@quantity = quantity
@manufacturer.extend Manufacturer
@payor.extend Payor
end
def call
(1..@quantity).each do |i|
@payor.debit @item.cost
@manufacturer.manufacture @item
end
end
end
class MarkupContext
def initialize(owner, item_name, percentage)
@owner = owner
@item_name = item_name
@percentage = percentage
end
def call
@owner.items.each do |item|
item.price = (item.cost + (item.cost * @percentage)) if item.name = @item_name
end
end
end
# A buyer wants to buy all items available from a seller up
# to a max number
class SalesContext
def initialize(seller, receiver, payor, item_name, quantity)
@seller = seller
@receiver = receiver
@payor = payor
@item_name = item_name
@quantity = quantity
@seller.extend Payee
@payor.extend Payor
end
def call
(1..@quantity).each do |i|
item = @seller.take "yoyo"
begin
@payor.debit item.price
@receiver.receive item
rescue
@seller.receive item
raise $!
end
end
end
end
class BankAccount
attr_accessor :balance
def initialize
balance = 0
end
end
class ItemOwner
attr_accessor :items
def initialize
@items = []
end
def take(item_name)
index = @items.index{|item| item.name == item_name}
raise "No more items named #{item_name}" if index.nil?
@items.delete_at(index)
end
def receive(item)
@items << item
end
end
class Person < ItemOwner
attr_accessor :bank_account
def initialize
super
@bank_account = BankAccount.new
end
def to_s
"Person(items: #{items.size}, cash: #{bank_account.balance})"
end
end
class Company < ItemOwner
attr_accessor :bank_account
def initialize
super
@bank_account = BankAccount.new
end
def to_s
"Company(items: #{items.size}, cash: #{bank_account.balance})"
end
end
class Item
attr_accessor :name, :cost, :price
def initialize(name, cost, price=0.0)
@name = name
@cost = cost
@price = price
end
end
module Manufacturer
def manufacture(item)
receive(item.dup)
end
end
module Payor
def debit(amount)
raise "Not enough funds" if @bank_account.balance < amount
bank_account.balance -= amount
end
end
module Payee
def credit(amount)
bank_account.balance += amount
end
end
manufacturer = Company.new
manufacturer.bank_account.balance = 1000000
wholeseller = Company.new
wholeseller.bank_account.balance = 500000
retailer = Company.new
retailer.bank_account.balance = 100000
customer = Person.new
customer.bank_account.balance = 20
yoyo = Item.new 'yoyo', 1.0
ManufacturingContext.new(manufacturer, manufacturer, yoyo, 100).call
puts manufacturer.to_s
MarkupContext.new(manufacturer, "yoyo", 0.4).call
SalesContext.new(manufacturer, wholeseller, wholeseller, "yoyo", 20).call
puts manufacturer.to_s
puts wholeseller.to_s
MarkupContext.new(wholeseller, "yoyo", 0.4).call
SalesContext.new(wholeseller, retailer, retailer, "yoyo", 10).call
puts wholeseller.to_s
puts retailer.to_s
MarkupContext.new(retailer, "yoyo", 0.4).call
SalesContext.new(retailer, customer, customer, "yoyo", 1).call
puts retailer.to_s
puts customer.to_s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment