Chapters
Chain-of-responsibility pattern is a behavioral design pattern that consists of command objects and processing objects. Command objects are objects that are being processed by processing objects.
Typically, every class in the chain has different responsibilities from one another. However, many implementations(such as UI event handling, servlet filters in Java and the example below) breaks this concept and allow several classes in the chain to take the same responsibility. This pattern promotes loose coupling as its processing objects are not closely tied up to command objects.
This example demonstrates chain-of-responsibility pattern.
Chain-of-responsibility pattern
Chain-of-responsibility pattern is a behavioral design pattern that consists of command objects and processing objects. Command objects are objects that are being processed by processing objects.
Typically, every class in the chain has different responsibilities from one another. However, many implementations(such as UI event handling, servlet filters in Java and the example below) breaks this concept and allow several classes in the chain to take the same responsibility. This pattern promotes loose coupling as its processing objects are not closely tied up to command objects.
This example demonstrates chain-of-responsibility pattern.
import java.util.List; import java.util.Arrays; public class ClientCode{ public static void main(String[] args){ Handler handler = new Adult(Arrays.asList(Handler.Fruits.all()), "Timothy"). addHandler( new YoungAdult( Arrays.asList(Handler.Fruits.APPLE, Handler.Fruits.GUAVA), "Samantha")). addHandler( new Child( Arrays.asList(Handler.Fruits.APPLE, Handler.Fruits.ORANGE), "Louis")); handler.offer(Handler.Fruits.APPLE); System.out.println(); handler.offer(Handler.Fruits.GUAVA); System.out.println(); handler.offer(Handler.Fruits.ORANGE); System.out.println(); handler.offer(Handler.Fruits.MELON); } } //functional interface interface Handler{ public enum Fruits{ AVOCADO, ORANGE, APPLE, GUAVA, MELON; public static Fruits[] all(){ return values(); } } //No need to add Handler reference after //Fruits reference. This method is in the //scope of Handler already // //classes that implement this method also //don't need to add Handler reference after //Fruits reference void offer(Fruits fruit); default Handler addHandler(Handler nextHandler){ return (fruit) -> { offer(fruit); nextHandler.offer(fruit); }; } } abstract class Patron{ protected List<Handler.Fruits> preferredFruit; protected String name; Patron(List<Handler.Fruits> preferredFruit, String name){ this.preferredFruit = preferredFruit; this.name = name; } protected boolean checkPreferredFruit(Handler.Fruits fruit){ boolean result = false; for(Handler.Fruits f : preferredFruit) if(f == fruit) result = true; return result; } } class Child extends Patron implements Handler{ Child(List<Handler.Fruits> preferredFruit, String name){ super(preferredFruit, name); } @Override public void offer(Fruits fruit){ if(!checkPreferredFruit(fruit)) return; System.out.println (name + ", a child, took " + fruit); } } class YoungAdult extends Patron implements Handler{ YoungAdult(List<Handler.Fruits> preferredFruit, String name){ super(preferredFruit, name); } @Override public void offer(Fruits fruit){ if(!checkPreferredFruit(fruit)) return; System.out.println (name + ", a young adult, took " + fruit); } } class Adult extends Patron implements Handler{ Adult(List<Handler.Fruits> preferredFruit, String name){ super(preferredFruit, name); } @Override public void offer(Fruits fruit){ if(!checkPreferredFruit(fruit)) return; System.out.println (name + ", an adult, took " + fruit); } } Result Timothy, an adult, took APPLE Samantha, a young adult, took APPLE Louis, a child, took APPLE Timothy, an adult, took GUAVA Samantha, a young adult, took GUAVA Timothy, an adult, took ORANGE Louis, a child, took ORANGE Timothy, an adult, took MELONIn the example above, fruits in the
Fruits
enum are command objects whereas Adult
, Child
and YoungAdult
instances are processing objects.
No comments:
Post a Comment