The delegation pattern is the idea of creating a new object by wrapping an existing one called the parent object. In order to reuse the object's features, the functions that have been defined for the new object can be delegated (also known as forwarded) to the parent.
Suppose that we have access to a banking library that provides some basic account management functionality. To understand how it works, let's take a look at the source code.
A bank account has been designed with the following mutable data structure:
mutable struct Account
account_number::String
balance::Float64
date_opened::Date
end
As part of the programming interface, the library also provides the field accessors (see Chapter 8, Robustness Patterns) and functions for making deposits, withdrawals, and transfers, as follows:
# Accessors
account_number(a::Account) = a.account_number
balance(a::Account) = a.balance
date_opened(a::Account) = a.date_opened
# Functions
function deposit!(a::Account, amount::Real)
a.balance += amount
return a.balance
end
function withdraw!(a::Account, amount::Real)
a.balance -= amount
return a.balance
end
function transfer!(from::Account, to::Account, amount::Real)
withdraw!(from, amount)
deposit!(to, amount)
return amount
end
Of course, in practice, such a banking library has to be a lot more complex than what is seen here. I suspect that when money goes in and out of a bank account, there are many downstream effects such as logging an audit trail, making the new balance available on a website, sending emails to the customer, and so on.
Let's move on and learn how we can utilize the delegation pattern.