# Golang - Chain of Responsibility Pattern

The Chain of Responsibility pattern is a behavioral design pattern that allows an object to pass a request along a chain of handlers until one of the handlers can handle the request. This pattern is useful when there are multiple objects that can handle a request, but we do not know which object can handle the request until runtime.

The Gang of Four, in their book "Design Patterns: Elements of Reusable Object-Oriented Software", first introduced the Chain of Responsibility pattern.

# Implementation in Golang

Let's implement the Chain of Responsibility pattern in Golang. We will use a realistic example where a customer's order is handled by different departments in a company.

```go
type Order struct {
    // ...
}

type OrderHandler interface {
    SetNext(OrderHandler) OrderHandler
    Handle(*Order) error
}

type OrderProcessor struct {
    handler OrderHandler
}

func (o *OrderProcessor) SetHandler(handler OrderHandler) {
    o.handler = handler
}

func (o *OrderProcessor) Process(order *Order) error {
    return o.handler.Handle(order)
}

type WarehouseHandler struct {
    next OrderHandler
}

func (w *WarehouseHandler) SetNext(next OrderHandler) OrderHandler {
    w.next = next
    return next
}

func (w *WarehouseHandler) Handle(order *Order) error {
    if order.WarehouseFilled {
        if w.next != nil {
            return w.next.Handle(order)
        }
        return nil
    }
    return errors.New("warehouse not filled")
}

type ShippingHandler struct {
    next OrderHandler
}

func (s *ShippingHandler) SetNext(next OrderHandler) OrderHandler {
    s.next = next
    return next
}

func (s *ShippingHandler) Handle(order *Order) error {
    if order.ShippingFilled {
        if s.next != nil {
            return s.next.Handle(order)
        }
        return nil
    }
    return errors.New("shipping not filled")
}

type BillingHandler struct {
    next OrderHandler
}

func (b *BillingHandler) SetNext(next OrderHandler) OrderHandler {
    b.next = next
    return next
}

func (b *BillingHandler) Handle(order *Order) error {
    if order.BillingFilled {
        if b.next != nil {
            return b.next.Handle(order)
        }
        return nil
    }
    return errors.New("billing not filled")
}

```

In the above code, we have defined the interface `OrderHandler` and a struct `OrderProcessor`. The `OrderProcessor` has a reference to an implementation of the `OrderHandler` interface.

We have also defined different handlers for different departments - `WarehouseHandler`, `ShippingHandler`, and `BillingHandler`. Each handler has a reference to the next handler in the chain.

The `Handle` function in each handler checks if the specific department has completed the order. If it has, it passes the request to the next handler in the chain. If not, it returns an error.

# Usage

Let's see how we can use the Chain of Responsibility pattern in our example.

```go
func main() {
    order := &Order{ /* ... */ }
    orderProcessor := &OrderProcessor{}

    warehouseHandler := &WarehouseHandler{}
    shippingHandler := &ShippingHandler{}
    billingHandler := &BillingHandler{}

    warehouseHandler.SetNext(shippingHandler)
    shippingHandler.SetNext(billingHandler)

    orderProcessor.SetHandler(warehouseHandler)

    if err := orderProcessor.Process(order); err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("Order processed successfully")
}

```

In the above code, we have created an order and an instance of the `OrderProcessor`. We have also created instances of the different handlers and set up the chain of responsibility.

Finally, we pass the order to the `OrderProcessor` and check if there were any errors.

# Conclusion

The Chain of Responsibility pattern is a powerful pattern that allows us to handle requests in a flexible and extensible way. In Golang, we can implement this pattern using interfaces and structs, as shown in the example above.

---

# References

* [**“Design Patterns: Elements of Reusable Object-Oriented Software**](https://amzn.to/3SJenIZ)” by Erich Gamma, John Vlissides, Ralph Johnson, and Richard Helm
