The chain of responsibility pattern is used to replace statements like if...else..if...else in a more objective-oriented form. The purpose of this pattern is to literally allow us to chain any number of objects, where each has the option of either handling a particular request, or deferring to the next object in the cycle.

Ex.

We have a set of steps on how to make a type of coffee. Instead of using If-Else statements to define guide, we can refactor our code through an array of responsibility chains. Each item in guide has a match of coffee and procedure properties.

The coffee recipes are from https://www.tripzilla.ph/coffee-recipes/16486.

const guide = [
        {
            coffee: function(coffee_type){
                return "affogato";
            },
            procedure:  function(coffee_type){
                steps = [
                        "1. Brew your coffee right before serving.", 
                        "2. Place your ice cream in a glass.",
                        "3. Drizzle your ice cream with chocolate syrup.",
                        "4. Pour your coffee over the ice cream."
                     ];
                return steps;
            }
        },
        {    
            coffee: function(coffee_type){
                return "caramel macchiato";
            },
            procedure:  function(coffee_type){
               steps = [
                        "1. Pour vanilla syrup into the bottom of a glass. Add ice cubes and pour milk.", 
                        "2. Slowly pour in cold brew concentrate.",
                        "3. Drizzle with caramel sauce."
                     ];
                return steps;
            }
        },
        {    
            coffee: function(coffee_type){
                return "chai latte";
            },
            procedure:  function(coffee_type){
                steps = [
                        "1. Pour your masala chai concentrate into a glass.", 
                        "2. Add coffee",
                        "3. Froth your milk with an electric frother or by shakin it in a mason jar.",
                        "4. Add sweetener to a taste."
                     ];
                return steps;
                }
        },
]

We traverse the array of responsibility chains. Once the responsibility is matched, the function will return directly.

function demo(coffee_type){
    for(let i=0;i<guide.length;i++){
        if(guide[i].coffee(coffee_type)==(coffee_type)){
            return guide[i].procedure(coffee_type);
        }
    }
}

demo("caramel macchiato");

Output:

[
    0: "1. Pour vanilla syrup into the bottom of a glass. Add ice cubes and pour milk."
    1: "2. Slowly pour in cold brew concentrate."
    2: "3. Drizzle with caramel sauce."
]

Note:

When to use objects

  • when you don't need order

When to use arrays

  • when you need order