Chain of Responsibility
The Chain of Responsibility pattern is a behavioral design pattern that allows an object to pass a request along a chain of potential handlers until the request is handled.
Here is a simple example of the Chain of Responsibility pattern:
trait Handler { fn set_next(&mut self, next: Box<dyn Handler>); fn handle(&self, request: &str); } struct BaseHandler { next: Option<Box<dyn Handler>>, } impl BaseHandler { fn new() -> Self { BaseHandler { next: None } } } impl Handler for BaseHandler { fn set_next(&mut self, next: Box<dyn Handler>) { self.next = Some(next); } fn handle(&self, request: &str) { if let Some(ref next) = self.next { next.handle(request); } } } struct ConcreteHandlerA { next: Option<Box<dyn Handler>>, } impl Handler for ConcreteHandlerA { fn set_next(&mut self, next: Box<dyn Handler>) { self.next = Some(next); } fn handle(&self, request: &str) { if request == "A" { println!("ConcreteHandlerA handled request: {}", request); } else { println!("ConcreteHandlerA passed the request"); if let Some(ref next) = self.next { next.handle(request); } } } } struct ConcreteHandlerB { next: Option<Box<dyn Handler>>, } impl Handler for ConcreteHandlerB { fn set_next(&mut self, next: Box<dyn Handler>) { self.next = Some(next); } fn handle(&self, request: &str) { if request == "B" { println!("ConcreteHandlerB handled request: {}", request); } else { println!("ConcreteHandlerB passed the request"); if let Some(ref next) = self.next { next.handle(request); } } } } fn main() { let mut handler = BaseHandler::new(); let mut handler_b = Box::new(ConcreteHandlerB { next: None }); let handler_a = Box::new(ConcreteHandlerA { next: None }); handler_b.set_next(handler_a); handler.set_next(handler_b); println!("Handle request A"); handler.handle("A"); println!("Handle request B"); handler.handle("B"); println!("Handle request C"); handler.handle("C"); }
In this example:
Handler
is a trait that defines the interface for handling requests.BaseHandler
is a base struct that implements the common behavior for setting the next handler and passing the request along the chain.ConcreteHandlerA
andConcreteHandlerB
are concrete implementations of theHandler
trait that handle specific requests.- The
main
function sets up the chain and tests the handlers with different requests.