Skip to content

Instantly share code, notes, and snippets.

@devotdev
devotdev / fetch_product_details.rb
Created January 21, 2026 10:28
Usage in a service
# app/services/fetch_product_details.rb
class FetchProductDetails
def initialize(api: Integration::CachingProductApiProxy.new)
@api = api
end
def call(sku)
@api.find_product(sku)
end
end
@devotdev
devotdev / caching_product_api_proxy.rb
Created January 21, 2026 10:28
Proxy – CachingProductApiProxy
# app/services/integration/caching_product_api_proxy.rb
module Integration
class CachingProductApiProxy
def initialize(real_api: SlowProductApi.new, cache: Rails.cache)
@real_api = real_api
@cache = cache
end
def find_product(sku)
@cache.fetch("product_api/#{sku}", expires_in: 5.minutes) do
@devotdev
devotdev / slow_product_api.rb
Created January 21, 2026 10:27
Real service – SlowProductApi
# app/services/integration/slow_product_api.rb
module Integration
class SlowProductApi
def find_product(sku)
# Simulate external HTTP request
sleep(2)
{ sku: sku, name: "Product #{sku}", price_cents: 1000 }
end
end
end
* Main Menu
* Products
- Laptops (/products/laptops)
- Monitors (/products/monitors)
* Account
- Profile (/account/profile)
- Settings (/account/settings)
- Help (/help)
@devotdev
devotdev / usage.rb
Created January 21, 2026 10:26
Usage
root = MenuGroup.new("Main Menu")
products = MenuGroup.new("Products")
products.add(MenuItem.new("Laptops", "/products/laptops"))
products.add(MenuItem.new("Monitors", "/products/monitors"))
account = MenuGroup.new("Account")
account.add(MenuItem.new("Profile", "/account/profile"))
account.add(MenuItem.new("Settings", "/account/settings"))
@devotdev
devotdev / menu_group.rb
Created January 21, 2026 10:25
Composite – menu group
# app/models/menu_group.rb
class MenuGroup < MenuComponent
attr_reader :name
def initialize(name)
@name = name
@children = []
end
def add(component)
@devotdev
devotdev / menu_item.rb
Created January 21, 2026 10:25
Leaf – single menu item
# app/models/menu_item.rb
class MenuItem < MenuComponent
attr_reader :name, :path
def initialize(name, path)
@name = name
@path = path
end
def render(indent: 0)
@devotdev
devotdev / menu_component.rb
Created January 21, 2026 10:24
Component interface
# app/models/menu_component.rb
class MenuComponent
def render(indent: 0)
raise NotImplementedError, "#{self.class} must implement #render"
end
end
@devotdev
devotdev / payments_controller.rb
Created January 21, 2026 10:23
Usage in controller
# app/controllers/payments_controller.rb
class PaymentsController < ApplicationController
def create
order = current_user.orders.find(params[:order_id])
transaction = PaymentFacade.new.process(order, params[:payment_method_token])
if transaction.success?
redirect_to order_path(order), notice: "Payment successful"
else
redirect_to order_path(order), alert: "Payment failed"
@devotdev
devotdev / payment_facade.rb
Created January 21, 2026 10:23
Facade – PaymentFacade
# app/facades/payment_facade.rb
class PaymentFacade
def initialize(
charge_gateway: Payment::ChargeGateway.new,
create_transaction_record: Payment::CreateTransactionRecord.new,
send_receipt: Payment::SendReceipt.new
)
@charge_gateway = charge_gateway
@create_transaction_record = create_transaction_record
@send_receipt = send_receipt