Javascript Luantan design pattern series (4) - combination mode (Composite)

Recommended for you: Get network issues from WhatsUp Gold. Not end users.

 


Preface

Blog talk about design patterns in many articles, I also benefit, including TerryLee, Lv Zhenyu and so on the design pattern of.NET series of articles, strongly recommended. For me, the development of good at the code, also have a certain understanding of design patterns, so I want to combine with Javascript to design the front side of “ design pattern, ” to the background “ &rdquo design pattern as a supplement;. The beginning of the series I'm with profound respect and humility, afraid of their own is not well written, but I also want to make a try, to hope to give some help, and secondly from writing articles to exercise myself by writing articles, three confidence to oneself; if not well written, welcome to clap brick, I will humbly to the blog master cattle people learn to ask; if it can be written, thank you support:)

Combination model is relatively simple, so start today's article.

Summary

It is part of the overall model, element has two forms, one is the simple elements, is a complex element, which is composed of complex elements of simple elements, so the client program to operate complex elements, sometimes it does not want to understand the internal which include simple elements, but also want to maintain simplicity simple elements, then, there will be a mix of mode, it can be abstracted into a tree structure, the simple elements as a leaf node, and complex elements of the non leaf node.

Definition

Combination mode allows you to compose objects into tree structures to represent “ whole / part of the hierarchical structure of &rdquo. The combination can make customers deal with the individual object and the object in a consistent manner.

The class diagram


The example analysis

Here I give a use menu navigation mode design:

Under the first effect chart:

Now analyze through combined mode, how to achieve it:

1 references the InterfaceAndClass.js file, as the inheritance interface structure and class, this not much said, please read the previous article,

2 add the MenuComponent.js file, as the Component interface or abstract class, here I used the form of interface:

var MenuComponent = new Interface("MenuComponent", [["getValue"]]);


3 add the MenuItem.js file, as Leaf simple elements, here refers to the menu of a leaf node:

复制代码

function MenuItem(text, title, href) {

this.text = text;

this.title = title;

this.href = href;

Interface.registerImplements(this, MenuComponent);

}

MenuItem.prototype = {

getValue : function() {

//

}

}

复制代码

Where text is the text displayed on the menu, title for tips on text characters, href for link oriented; and let it inherits the MenuComponent interface,


4 add the Menu.js file, as Composite composite element, which is composed of a series of simple elements Leaf:

复制代码

function Menu(text, title, href) {

this.menuComponents = new Array();

this.text = text;

this.title = title;

this.href = href;

Interface.registerImplements(this, MenuComponent);

}

Menu.prototype = {

getValue : function() {

//

},

add : function(component) {

this.menuComponents.push(component);

},

remove : function(component) {

for(var i = 0, len = this.menuComponents.length; i < len; i++)

{

if(this.menuComponents[i] == component)

{

this.menuComponents.splice(i,1);

break;

}

}

},

removeAt : function(index) {

if(this.menuComponents.length <= index)

{

this.menuComponents.splice(index, 1);

}

else

{

throw new Error("The index operation array exceeds the upper limit");

}

}

}

复制代码

It inherits the MenuAComponent interface, so the MenuItem using the same interface method calls can be unified, such simple elements and complex elements, the add method is used to add a class component, where component is Menu, or MenuItem; remove method is used to delete the specified class component; removeAt method used to delete the corresponding index component; getValue method to get the menu data,

Let's get a tree from the instance:

We can see from the figure above, in fact 1 menus, menu menu menu 2-1, 2-2-1, 2-2-2, 2-3 3-1 menu, menu, menu 4 belong to Leaf, i.e. MenuItem class,

Menu menu menu 2, 2-2, 3 belong to Composite, i.e. Menu class,

The Menu class's GetValue method can traverse the sub node array, get all the sub node menu data,

for(var i = 0, len = this.menuComponents.length; i < len; i++)

{

str += this.menuComponents[i].getValue();

}

The this.menuComponents[i].getValue (getValue) is a method of the Menu class, also can be the getValue method of the MenuItem class,

It can complete all the node traversal.

Then the complete code is MenuItem.js and Menu.js.:

function MenuItem(text, title, href) {

this.text = text;

this.title = title;

this.href = href;

Interface.registerImplements(this, MenuComponent);

}

MenuItem.prototype = {

getValue : function() {

var str = "<li class=\"Menu-Leaf\" title=\"" + this.title + "\"><a href=\"" + this.href + "\">" + this.text + "</a></li>";

return str;

}

}


function Menu(text, title, href) {

this.menuComponents = new Array();

this.text = text;

this.title = title;

this.href = href;

Interface.registerImplements(this, MenuComponent);

}

Menu.prototype = {

getValue : function() {

if(this.menuComponents.length == 0)

{

throw new Error(this.text + "No sub menu menu");

}

var str = "<li class=\"Menu-WithChildren\" title=\"" + this.title + "\"><a class=\"Menu-Link\" href=\"" + this.href + "\">" + this.text + "</a>";

str += "<ul>";

for(var i = 0, len = this.menuComponents.length; i < len; i++)

{

str += this.menuComponents[i].getValue();

}

str += "</ul>";

return str;

},

add : function(component) {

this.menuComponents.push(component);

},

remove : function(component) {

for(var i = 0, len = this.menuComponents.length; i < len; i++)

{

if(this.menuComponents[i] == component)

{

this.menuComponents.splice(i,1);

break;

}

}

},

removeAt : function(index) {

if(this.menuComponents.length <= index)

{

this.menuComponents.splice(index, 1);

}

else

{

throw new Error("The index operation array exceeds the upper limit");

}

}

}



5 then add a class Menu MenuOpr:

复制代码

var MenuOpr = {

list : new Array(),

add : function(component) {

this.list.push(component);

},

print : function(container) {

var str = "<ul class=\"Menu\">";

for(var i = 0, len = this.list.length; i < len; i++) {

str += this.list[i].getValue();

}

document.getElementById(container).innerHTML = str + "</ul>";

}

}

复制代码


6 the combination mode to write the calling code:

复制代码

var menu1 = new MenuItem("Menu 1 ", 1" menu","#");

var menu2 = new Menu("Menu 2 ", 2" menu","#");

var menu2_1 = new MenuItem("2-1 "menu, menu 2-1  "", "#");

var menu2_2 = new Menu("2-2 "menu, menu 2-2  "", "#");

var menu2_2_1 = new MenuItem("2-2-1 "menu, menu 2-2-1  "", "#");

var menu2_2_2 = new MenuItem("2-2-2 "menu, menu 2-2-2  "", "#");

var menu2_3 = new MenuItem("The menu 2-3 "," 2-3 menu","#");

menu2.add(menu2_1);

menu2.add(menu2_2);

menu2_2.add(menu2_2_1);

menu2_2.add(menu2_2_2);

menu2.add(menu2_3);

var menu3 = new Menu("Menu 3 ", 3" menu","#");

var menu3_1 = new MenuItem("The menu 3-1 "," 3-1 menu","#");

menu3.add(menu3_1);

var menu4 = new MenuItem("Menu 4 ", 4" menu","#");

MenuOpr.add(menu1);

MenuOpr.add(menu2);

MenuOpr.add(menu3);

MenuOpr.add(menu4);

MenuOpr.print("main_container");

复制代码

Main_container is a div layer ID, code here not much said, one can see understand.

Of course, this menu or a lot of method, but I this is certainly not optimal, here I just provide a combined mode of thinking.,

If in accordance with the Convention, you can put MenuItem into Menu, MenuItem to Menu, this code, you is it right? More like.?

This is for your own research.!

Finally, say due to the example in this paper menu style using li:hover approach to eject the sub menu, because this method is not valid for the IE7 version, so here refers to the two JS files in the open source projects of cssfriendly, MenuAdapter.js and AdapterUtils.js, to put them into the project reference to come in, so that the menu compatible with the IE7 version of the browser.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Posted by Dolores at November 15, 2013 - 9:26 AM