The Composite Pattern in ECMAScript/JavaScript
An Introduction with Examples |
Prof. David Bernstein |
Computer Science Department |
bernstdh@jmu.edu |
In UML:
A Recipe System
Instruction
Class
/** * An encapsulation of an Instruction * * @constructor * @param {string} text - The text of the Instruction */ function Instruction(text) { "use strict"; this.text = text; } /** * Display this Instruction (in a popup window) * * (Required by the Step interface) */ Instruction.prototype.display = function() { "use strict"; window.alert(this.text); };
Recipe
Class/** * An encapsulation of a Recipe * * @constructor * @param {string} title - The title of the Recipe (e.g., "Prepare toast") */ function Recipe(title) { "use strict"; this.title = title; this.steps = new Array(); } /** * Add a Step to this Recipe * * Note: Because we are using the Composite Pattern, the Recipe class * implements the Step. So, a Recipe can be added * to a Recipe (as can any other class that implements the interface). * * @param {Step} step - The Step to add */ Recipe.prototype.add = function(step) { "use strict"; this.steps.push(step); }; /** * Display this Recipe (in a sequence of popup windows) * * (Required by the Step interface) */ Recipe.prototype.display = function() { "use strict"; var details, i; details = window.confirm(this.title+". \n Do you need details?"); if (details){ for (i=0; i<this.steps.length; i++){ this.steps[i].display(); } window.alert(this.title + ": Complete!"); } };
<!DOCTYPE html> <html> <head> <script src="Instruction.js" type="text/javascript"></script> <script src="Recipe.js" type="text/javascript"></script> </head> <body> <script type="text/javascript"> var i, eggsbenedict, hollandaise, sweetyolks; eggsBenedict = new Recipe("Prepare Eggs Benedict"); hollandaise = new Recipe("Prepare Hollandaise sauce"); sweetYolks = new Recipe("Prepare sweetened egg yolks"); // Eggs Benedict eggsBenedict.add(hollandaise); i = new Instruction("Toast an English muffin"); eggsBenedict.add(i); i = new Instruction("Poach eggs until whites are soft"); eggsBenedict.add(i); i = new Instruction("Grill Canadian bacon"); eggsBenedict.add(i); i = new Instruction("Plate the completed dish"); eggsBenedict.add(i); // Hollandaise Sauce hollandaise.add(sweetYolks); i = new Instruction("Bring 1 inch of water in a saucepan to a simmer"); hollandaise.add(i); i = new Instruction("Place the bowl of sweetened yolks over the pan"); hollandaise.add(i); i = new Instruction("Whisk for 3 to 5 minutes"); hollandaise.add(i); i = new Instruction("Add the butter"); hollandaise.add(i); i = new Instruction("Whisk until butter is incorporated"); hollandaise.add(i); i = new Instruction("Add sugar"); hollandaise.add(i); i = new Instruction("Add salt, lemon juice, and cayenne pepper"); hollandaise.add(i); // Sweet Yolks i = new Instruction("Place yolks in a bowl"); sweetYolks.add(i); i = new Instruction("Add 1 teaspoon of water"); sweetYolks.add(i); i = new Instruction("Whisk the yolks until they are light and frothy"); sweetYolks.add(i); eggsBenedict.display(); </script> </body> </html>