Patterns: behavior · 3 MIN READ
Chain of Responsibility: ordered handlers
Stop or delegate deliberately and make short-circuit order visible.
Stop or delegate deliberately and make short-circuit order visible. A chain passes a request through handlers that can decide whether to continue. Trace the worked Go example, then compare the benefit with the cost before applying this design to your own project.
Behavioral pattern · A MAP OF THE IDEA
- First handler checks the request
- Failure short-circuits the chain
- Next handler receives accepted input
Useful when
- Handlers can independently accept or reject
- Middleware concerns should be composable
Watch out
- Short-circuit order changes behavior
- Silent swallowing makes failures hard to trace
Implementation & operation cost: Low to medium
Fit depends on the task
Editorial suitability, not benchmarks or a universal ranking. Styles describe different axes and can be combined.
The design decision
A chain passes a request through handlers that can decide whether to continue. Validation commonly stops at the first failure. Unlike an unconditional pipeline, a responsibility chain defines which handler accepts, rejects or delegates the request.
A complete Go example
Read this program from the entry point and follow the calls shown in the diagram. The output is included at the end so you can check the behavior without a compiler.
package main
import (
"errors"
"fmt"
"strings"
)
type Check func(string) error
func Validate(input string, checks ...Check) error {
for _, check := range checks {
if err := check(input); err != nil {
return err
}
}
return nil
}
func NonEmpty(s string) error {
if strings.TrimSpace(s) == "" {
return errors.New("empty")
}
return nil
}
func Short(s string) error {
if len(s) > 5 {
return errors.New("too long")
}
return nil
}
func main() {
fmt.Println(Validate("", NonEmpty, Short))
fmt.Println(Validate("gopher", NonEmpty, Short))
}
// Output:
// empty
// too long
Validate delegates in order and returns immediately on an error. The second check is never asked about an empty string after the first failure. An HTTP middleware chain can use a similar continuation shape with a next handler.
Tradeoffs and the simpler alternative
Ordering is part of behavior: authentication should usually precede work that leaks private data. Keep chains observable and avoid handlers that silently swallow failures. If every step must always run, an explicit sequence or result-collecting validator may be clearer.
TAKE THIS WITH YOU
May handle, reject or delegate in a defined order. Ordering is part of behavior: authentication should usually precede work that leaks private data. Keep chains observable and avoid handlers that silently swallow failures. If every step must always run, an explicit sequence or result-collecting validator may be clearer.
Check your understanding
Which statement best describes Chain of Responsibility: ordered handlers?
Go to the source
Progress stays in this browser. No account needed.