How Procedural design compares to functional Inversion of Control (IoC)

The client request is wrapped by the Authorization, LoadBalancing, Logging, and FaultTolerance decorators. When a client request is executed, the functionality in those decorators will be injected into the flow by our Decorator framework, as shown in the following diagram:

In procedural programming, the main() function would be in control of the flow of logic. The code would be monolithic and tightly coupled. For example, to implement Authorization, the programmer would insert the following line somewhere before the request is performed:

request.Header.Add("Authorization", token)

The logic of FaultTolerance and LoadBalancing would likely look like spaghetti code.

By programming the Decorator functions, we adhere to the client interface as follows:

type Client interface {
Do(*http.Request) (*http.Response, error)
}

Each decorator will be a separate function-specific component.