CODESAMPLE
Self-contained Systems - Ruby
The Self-Contained System pattern promotes building modular, reusable components that encapsulate all their dependencies. Each system should have a clear interface and minimal external exposure. This fosters independence, simplifies testing, and reduces coupling.
Here, we model a simple EmailService as a self-contained system. It encapsulates its dependency on a message construction object (EmailComposer) within the service itself. The external interface only requires specifying a recipient and subject; the internal composition of the email is handled transparently.
Ruby’s strong support for composition and object instantiation lends itself naturally to this pattern. The EmailService class directly creates the EmailComposer instance it needs, avoiding external dependency injection and keeping all related logic together. This approach is common in Ruby for creating focused, cohesive units of functionality.
# lib/email_service.rb
class EmailComposer
def compose(recipient, subject, body)
"To: #{recipient}\nSubject: #{subject}\n\n#{body}"
end
end
class EmailService
def initialize
@composer = EmailComposer.new
end
def send_email(recipient, subject, body)
email_content = @composer.compose(recipient, subject, body)
send_raw_email(email_content) # Simulate sending - replace with actual SMTP logic
true # Indicate success
end
private
def send_raw_email(content)
puts "Sending email to:\n#{content}"
end
end
# Example Usage:
if __FILE__ == $0
service = EmailService.new
service.send_email("user@example.com", "Hello", "This is the email body.")
end