Composition mode combines objects into a tree structure to represent the "part-whole" hierarchy. The combination mode enables users to use single objects and combined objects consistently.
It blurs the concepts of simple elements and complex elements in our tree structure problems. The client program can process complex elements in the same way as simple elements, thus allowing the client program to resolve the internal structure of complex elements. coupling. It can help developers classify multiple objects with similar functions and improve standardized design
There are many examples of hierarchical data structures, making the combination pattern very useful. A common example of a hierarchical data structure is what you encounter every time you use a computer: the file system. A file system consists of directories and files. Each directory can contain content. The contents of a directory can be files or directories. In this way, the computer's file system is organized in a recursive structure. If you want to describe such a data structure, then you can use the composite pattern.
Involving roles
Features
There are two types of objects in the hierarchy of the composite pattern: leaf objects and composite objects. This is a recursive definition, but it is also useful. The reason is that a composite object can be composed of other composite objects and leaf objects, but the leaf object no longer contains sub-objects. The composite object is used for the classification of leaf nodes

Design
Here we borrow the diagram of javascript design pattern to illustrate the design of the combination pattern
Interface is the object declaration interface in the combination. Where appropriate, implement the default behavior of interfaces common to all classes. Declare an interface for accessing and managing Component subcomponents.
Field represents the leaf node object in the combination. The leaf node has no child nodes and can be designed as an abstract class. Different categories of leaf objects can be designed through inheritance.
Composite defines sub-node behaviors, which are used to store sub-components and implement operations related to sub-components in the Component interface, such as add (add) and delete (remove).

- ##Interface
1 2 3 4 | var Composite = new Interface( 'Composite' , [ 'add' , 'remove' , 'getChild' ]);
var FormItem = new Interface( 'FormItem' , [ 'save' ]);
|
Copy after login
- Combined Object Class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | var CompositeForm = function (id, method, action) {
this.formComponents = [];
this.element = document.createElement( 'form' );
this.element.id = id;
this.element.method = method || 'POST' ;
this.element.action = action || '#' ;
};
CompositeForm.prototype.add = function (child) {
Interface.ensureImplements(child, Composite, FormItem);
this.formComponents.push(child);
this.element.appendChild(child.getElement());
};
CompositeForm.prototype.remove = function (child) {
for ( var i = 0, len = this.formComponents.length; i < len; i++) {
if (this.formComponents[i] === child) {
this.formComponents.splice(i, 1);
break ;
}
}
};
CompositeForm.prototype.getChild = function (i) {
return this.formComponents[i];
};
CompositeForm.prototype.save = function () {
for ( var i = 0, len = this.formComponents.length; i < len; i++) {
this.formComponents[i].save();
}
};
CompositeForm.prototype.getElement = function () {
return this.element;
};
|
Copy after login
- Leaf Object Class
The leaf object can be a simple class, or it can be designed as an abstract class to construct different types of leaves. Here, abstract classes are used to design different types of leaves
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | var Field = function (id) {
this.id = id;
this.element;
};
Field.prototype.add = function () {};
Field.prototype.remove = function () {};
Field.prototype.getChild = function () {};
Field.prototype.save = function () {
setCookie(this.id, this.getValue);
};
Field.prototype.getElement = function () {
return this.element;
};
Field.prototype.getValue = function () {
throw new Error( 'Unsupported operation on the class Field.' );
};
|
Copy after login
- InputField class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | var InputField = function (id, label) {
Field.call(this, id);
this.input = document.createElement( 'input' );
this.input.id = id;
this.label = document.createElement( 'label' );
var labelTextNode = document.createTextNode(label);
this.label.appendChild(labelTextNode);
this.element = document.createElement( 'p' );
this.element.className = 'input-field' ;
this.element.appendChild(this.label);
this.element.appendChild(this.input);
};
extend(InputField, Field);
InputField.prototype.getValue = function () {
return this.input.value;
};
|
Copy after login
- TextareaField class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | var TextareaField = function (id, label) {
Field.call(this, id);
this.textarea = document.createElement( 'textarea' );
this.textarea.id = id;
this.label = document.createElement( 'label' );
var labelTextNode = document.createTextNode(label);
this.label.appendChild(labelTextNode);
this.element = document.createElement( 'p' );
this.element.className = 'input-field' ;
this.element.appendChild(this.label);
this.element.appendChild(this.textarea);
};
extend(TextareaField, Field);
TextareaField.prototype.getValue = function () {
return this.textarea.value;
};
|
Copy after login
- SelectField class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | var SelectField = function (id, label) {
Field.call(this, id);
this.select = document.createElement( 'select' );
this.select.id = id;
this.label = document.createElement( 'label' );
var labelTextNode = document.createTextNode(label);
this.label.appendChild(labelTextNode);
this.element = document.createElement( 'p' );
this.element.className = 'input-field' ;
this.element.appendChild(this.label);
this.element.appendChild(this.select);
};
extend(SelectField, Field);
SelectField.prototype.getValue = function () {
return this.select.options[this.select.selectedIndex].value;
};
|
Copy after login
Use
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | var contactForm = new CompositeForm( 'contact-form' , 'POST' , 'contact.php' );
contactForm.add( new InputField( 'first-name' , 'First Name' ));
contactForm.add( new InputField( 'last-name' , 'Last Name' ));
contactForm.add( new InputField( 'address' , 'Address' ));
contactForm.add( new InputField( 'city' , 'City' ));
contactForm.add( new SelectField( 'state' , 'State' , stateArray));
contactForm.add( new InputField( 'zip' , 'Zip' ));
contactForm.add( new TextareaField( 'comments' , 'Comments' ));
addEvent(window, 'unload' , contactForm.save);
|
Copy after login
The combination mode is suitable for operating a large number of objects, and the operating objects have hierarchical relationships. By classifying objects, the coupling between objects is weakened. This mode makes the code more modular and hierarchical. More distinct and better maintainability
Related recommendations:
Detailed explanation of js bridge design pattern
General basic design pattern in Node.js Example analysis
Detailed explanation of js proxy design pattern
The above is the detailed content of Detailed explanation of js combination design pattern. For more information, please follow other related articles on the PHP Chinese website!