A dependency is an external component or service a program requires to perform its work. In a money converter, a bank or exchange-rate API supplies data that conversion needs. section 6.5
Separate fetching exchange rates from using them. Keep the money package unaware of the data source, and provide the rate provider through a contract. This inversion of control reduces assumptions, isolates side effects, and makes testing and replacement easier. section 6.5
Apply the dependency pattern by:
- Defining the smallest interface where the consumer needs it, rather than designing a shared interface in advance. section 6.5.5
- Passing the implementation into Convert so the caller chooses the exchange-rate source. section 6.5.5
- Replacing the real provider with a stub during tests or while an unavailable service is still being developed. section 6.5 section 6.5.5
- Wrapping provider errors and returning them to the caller instead of hiding dependency failures. section 6.5.5
A replaceable rate provider
Convert accepts an exchangeRates implementation. Production code can call the European Central Bank client; tests can pass stubRate with a fixed rate or configured error. Passing nil instead causes a runtime nil-pointer panic when Convert calls FetchExchangeRate. section 6.5 section 6.5.5
Listing 6.50 exchangerates.go: Interface definition
type exchangeRates interface { #1
FetchExchangeRate(source, target Currency) (ExchangeRate, error)
}
Inspect the minimal exchangeRates interface used by the consumer. section 6.5.5
Listing 6.51 convert.go: Final implementation
// Convert applies the change rate to convert an amount to a target currency.
func Convert(
amount Amount, to Currency, rates exchangeRates) (Amount, error) {
// fetch the change rate for the day
r, err := rates.FetchExchangeRate(amount.currency, to) #1
if err != nil {
return Amount{}, fmt.Errorf(
"cannot get change rate: %w", err) #2
}
convertedValue := applyExchangeRate(amount, to, r)
if err := convertedValue.validate(); err != nil {
return Amount{}, err
}
return convertedValue, nil
}
Inspect Convert receiving the dependency, fetching a rate, wrapping errors, and validating the result. section 6.5.5


























