A delegate is a helper object used by another object. The delegator may send the delegate certain messages, and provide a default implementation when there is no delegate or the delegate does not respond to a message. This pattern is heavily used in Cocoa framework on Mac OS X. See also wp:Delegation pattern.

Objects responsibilities:

Delegator:

 Keep an optional delegate instance.
 Implement "operation" method, returning the delegate "thing" if the delegate respond to "thing", or the string "default implementation".
Delegate:

 Implement "thing" and return the string "delegate implementation"
Show how objects are created and used. First, without a delegate, then with a delegate that does not implement "thing", and last with a delegate that implements "thing".

local function Delegator()
  return {
    operation = function(self)
      if (type(self.delegate)=="table") and (type(self.delegate.thing)=="function") then
        return self.delegate:thing()
      else
        return "default implementation"
      end
    end
  }
end
 
local function Delegate()
  return {
    thing = function(self)
      return "delegate implementation"
    end
  }
end
 
local function NonDelegate(which)
  if (which == 1) then return true -- boolean
  elseif (which == 2) then return 12345 -- number
  elseif (which == 3) then return "Hello" -- string
  elseif (which == 4) then return function() end -- function
  elseif (which == 5) then return { nothing = function() end } -- table (without "thing")
  elseif (which == 6) then return coroutine.create(function() end) -- thread
  elseif (which == 7) then return io.open("delegates.lua","r") -- userdata (if exists, or nil)
  end
end
 
-- WITH NO (NIL) DELEGATE
local d = Delegator()
assert(d:operation() == "default implementation")
 
-- WITH A NON-DELEGATE
for i = 1, 7 do
  d.delegate = NonDelegate(i)
  assert(d:operation() == "default implementation")
end
 
-- WITH A PROPER DELEGATE
d.delegate = Delegate()
assert(d:operation() == "delegate implementation")
 
print("pass")