Introduced
Combined mode (composite) combines objects into a tree structure to represent a "partial-whole" hierarchy, which makes the user consistent in the use of individual objects and composite objects.
The common scene has the control mechanism in the asp.net (that is, it can contain child controls, can be recursively manipulated, add, remove child control), similar to the DOM mechanism, a DOM node can contain child nodes, whether the parent or child nodes have additions, deletions, The common function of traversing child nodes. So the key to the combinatorial pattern is to have an abstract class that can represent both child elements and parent elements.
Body
For example, a restaurant offers a variety of dishes, each with a menu, the menu lists the restaurant's occasional dishes, breakfast cakes, lunch, dinner, and so on, each with a variety of menu items, assuming that either the menu item or the entire menus should be printable, and you can add subkeys, For example, the lunch can add new dishes, and menu items coffee can also add sugar ah or something.
In this case, we can use the combination to represent the content as a hierarchy. Let's break down our implementation steps individually.
The first step is to implement our "abstract class" function MenuComponent:
Copy Code code as follows:
var menucomponent = function () {
};
MenuComponent.prototype.getName = function () {
throw new Error ("This method must be overridden!");
};
MenuComponent.prototype.getDescription = function () {
throw new Error ("This method must be overridden!");
};
MenuComponent.prototype.getPrice = function () {
throw new Error ("This method must be overridden!");
};
MenuComponent.prototype.isVegetarian = function () {
throw new Error ("This method must be overridden!");
};
MenuComponent.prototype.print = function () {
throw new Error ("This method must be overridden!");
};
MenuComponent.prototype.add = function () {
throw new Error ("This method must be overridden!");
};
MenuComponent.prototype.remove = function () {
throw new Error ("This method must be overridden!");
};
MenuComponent.prototype.getChild = function () {
throw new Error ("This method must be overridden!");
};
This function provides 2 types of methods, one is to get information, such as price, name, and so on, the other is a common operation method, such as printing, add, delete, Get submenu.
The second step is to create a basic menu item:
Copy Code code as follows:
var MenuItem = function (sname, sdescription, Bvegetarian, Nprice) {
Menucomponent.apply (this);
This.sname = sname;
This.sdescription = sdescription;
This.bvegetarian = Bvegetarian;
This.nprice = Nprice;
};
Menuitem.prototype = new MenuComponent ();
MenuItem.prototype.getName = function () {
return this.sname;
};
MenuItem.prototype.getDescription = function () {
return this.sdescription;
};
MenuItem.prototype.getPrice = function () {
return this.nprice;
};
MenuItem.prototype.isVegetarian = function () {
return This.bvegetarian;
};
MenuItem.prototype.print = function () {
Console.log (This.getname () + ":" + this.getdescription () + "," + this.getprice () + "euros");
};
As you can see from the code, we've only redesigned the 4 methods and print methods for obtaining information, without overloading the other 3 operations, because the basic dishes do not contain the means to add, remove, and get the sub-items.
The third step is to create a vegetable product:
Copy Code code as follows:
var Menu = function (sname, sdescription) {
Menucomponent.apply (this);
This.amenucomponents = [];
This.sname = sname;
This.sdescription = sdescription;
This.createiterator = function () {
throw new Error ("This method must to be overwritten!");
};
};
Menu.prototype = new MenuComponent ();
Menu.prototype.add = function (omenucomponent) {
Add a sub-vegetable product
This.aMenuComponents.push (omenucomponent);
};
Menu.prototype.remove = function (omenucomponent) {
Delete a sub-vegetable product
var amenuitems = [];
var nmenuitem = 0;
var nlenmenuitems = this.aMenuComponents.length;
var oitem = null;
for (; Nmenuitem < nlenmenuitems;) {
Oitem = This.amenucomponents[nmenuitem];
if (oitem!== omenucomponent) {
Amenuitems.push (Oitem);
}
Nmenuitem = Nmenuitem + 1;
}
This.amenucomponents = Amenuitems;
};
Menu.prototype.getChild = function (nindex) {
Gets the specified sub-vegetable product
return This.amenucomponents[nindex];
};
Menu.prototype.getName = function () {
return this.sname;
};
Menu.prototype.getDescription = function () {
return this.sdescription;
};
Menu.prototype.print = function () {
Print the current dish and all the sub dishes
Console.log (This.getname () + ":" + this.getdescription ());
Console.log ("--------------------------------------------");
var nmenucomponent = 0;
var nlenmenucomponents = this.aMenuComponents.length;
var omenucomponent = null;
for (; nmenucomponent < nlenmenucomponents;) {
Omenucomponent = This.amenucomponents[nmenucomponent];
Omenucomponent.print ();
Nmenucomponent = nmenucomponent + 1;
}
};
Note the above code, in addition to the implementation of the Add, delete, get methods, print printing method is to first print the current menu information, and then loop through the printing of all the sub-product information.
The fourth step is to create the specified dish:
We can create a few authentic dishes, such as dinner, coffee, pastries, and so on, all of which are using menu as its prototype, code as follows:
Copy Code code as follows:
var dinnermenu = function () {
Menu.apply (this);
};
Dinnermenu.prototype = new Menu ();
var cafemenu = function () {
Menu.apply (this);
};
Cafemenu.prototype = new Menu ();
var pancakehousemenu = function () {
Menu.apply (this);
};
Pancakehousemenu.prototype = new Menu ();
Step fifth, create the top-most menu container--Menu:
Copy Code code as follows:
var mattress = function (Amenus) {
This.amenus = Amenus;
};
Mattress.prototype.printMenu = function () {
This.aMenus.print ();
};
The function receives a menu array as a parameter, and the value provides a Printmenu method for printing all the menu contents.
Step sixth, call mode:
Copy Code code as follows:
var opancakehousemenu = new Menu ("Pancake House Menu", "breakfast");
var odinnermenu = new Menu ("Dinner menu", "Lunch");
var ocoffeemenu = new Menu ("Cafe menu", "Dinner");
var oallmenus = new Menu ("All MENUS", "all MENUS combined");
Oallmenus.add (Opancakehousemenu);
Oallmenus.add (Odinnermenu);
Odinnermenu.add (New MenuItem ("Pasta", "spaghetti with marinara sauce, and a slice of sourdough bread", true, 3.89));
Odinnermenu.add (Ocoffeemenu);
Ocoffeemenu.add (New MenuItem ("Express", "Coffee from Machine", false, 0.99));
var omattress = new Mattress (oallmenus);
Console.log ("---------------------------------------------");
Omattress.printmenu ();
Console.log ("---------------------------------------------");
Familiar with the ASP.net control development students, do not look familiar?
Summarize
The usage scenario for the combined mode is very clear:
You want to represent the part of the object-the whole hierarchy;
You want users to ignore the difference between a grouped object and a single object, and the user will uniformly use all the objects in the composite structure (method)
In addition, the pattern is often used with adorners, which usually have a common parent class (i.e., prototypes), so the decorations must support component interfaces with Add, remove, and getchild operations.