Back to Course

Practice · SOLID · ISP · Card 9

Why does this method take a whole User?

A function that asks for a User. It only ever reads one attribute. The argument is fatter than the dependency. What does that cost?

The code

A class that sends a one-off email. It takes a User.

class NotifyAdmin
  def call(user, subject, body)
    AdminMailer.with(
      to: user.email,
      subject: subject,
      body: body
    ).admin_notice.deliver_later
  end
end

# Callers:
NotifyAdmin.new.call(current_user, "New signup", "...")
NotifyAdmin.new.call(Admin.find(1), "Backup ran", "...")
NotifyAdmin.new.call(User.system_bot, "Cleanup", "...")

The question

NotifyAdmin only ever calls user.email. What's the cost of asking for a whole User object — and what should the parameter actually be?

Take a moment. A method's signature is a promise about what it needs. Asking for more than you need couples your caller to types they shouldn't have to provide. What's the smallest "interface" this method actually depends on?