domains / / chef/chef
Clear abstraction boundaries
Design APIs with clear and consistent abstraction boundaries to maintain code quality and prevent interface leakage between different system layers.
Design APIs with clear and consistent abstraction boundaries to maintain code quality and prevent interface leakage between different system layers.
Key principles:
- Separate CLI and API interfaces: CLI tools should not return API-style responses, and API endpoints should not handle CLI-specific concerns.
# Incorrect - CLI tool returning HTTP-like response { "status" => 200, "message" => "Success" } if @calling_request != "CLI" # Better approach - wrap the functionality with appropriate interfaces def perform_upload # Upload functionality here return true # Simple boolean for CLI end def api_upload perform_upload { "status" => 200, "message" => "Success" } # HTTP-style response for API end - Use proper method signatures: Prefer explicit keyword arguments over option hashes for better readability, documentation, and forward compatibility.
# Avoid this pattern - hard to document, using a generic options hash def powershell_exec(script, options = {}) timeout = options.fetch(:timeout, nil) # ... end # Better pattern - explicit keyword arguments with defaults def powershell_exec(script, interpreter: :powershell, timeout: nil) # Implementation... end - Place functionality at the appropriate abstraction level: Methods and properties should exist at the level where they are most logically connected.
# Avoid adding HTTP-specific error handling in generic resources class Resource # This doesn't belong here - too specific private def http_request_errors source.map do |msg| uri = URI.parse(msg) "Error connecting to #{msg} - Failed to open TCP connection to #{uri.host}:#{uri.port}" end end end # Better: Place in the specific resource that needs it class RemoteFileResource < Resource private def http_request_errors # Implementation... end end
Following these principles creates more maintainable, testable, and adaptable code by ensuring that each component has a clear, focused responsibility.