JS设计模式之组合模式

来源:互联网 发布:淘宝上老克勒卖假黄金 编辑:程序博客网 时间:2024/05/20 14:17

       组合模式就是指在页面表现中,通过一条指令而达到在多个对象中的复杂的递归行为,就是通过控制一个对象,不过该对象复杂的递归下去又是很多复杂的对象,同时控制对象的行为。这样简化代码,可维护,复杂的对象的行为委托给一个对象。

      组合模式确实能对于工作能起到简化作用,组合对象实现某一操作时,通过递归,向下传递到所有的组成对象,在存在大批对象时,假如页面的包含许多拥有同样功能的对象,只需要操作组合对象即可达到目标。在存在存在着某种的层次结构,并且其中的一部分要实现某些操作,即可使用组合模式。

    下面是组合模式书上的例子,展示了表单验证与图片阅读器。

        表单验证中,需要做的工作是表单的保存、恢复和验证表单中的值,然而表单的数量是未知数,类型是未知数,只有功能能确定的情况下,使用组合模式无疑最好,通过给每个表单添加功能,然后一个表单对象组合起来,通过操作表单对象即可达到操作表单。

        图片阅读器与表单验证基本一样,通过汇合操作图片。

<!DOCTYPE HTML><html><head><style></style></head><body><input value="存储" type="button" onclick="a()" /><input value="取出" type="button" onclick="b()" /><input value="隐藏" type="button" onclick="c()" /><input value="显示" type="button" onclick="d()" /></body><script type="text/javascript">    //存储的值  var value_content = {};function setCookie(name, value) {value_content[name] = value;}function getCookie(name) {return value_content[name];}    //表单组合对象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) {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 (child == this.formComponents[i]) {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.restore = function() {for ( var i = 0, len = this.formComponents.length; i < len; i++) {this.formComponents[i].restore();}}CompositeForm.prototype.getElement = function() {return this.element;}    //接口方法var Field = function(id) {this.id = id;this.element;this.content;};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('错误');}Field.prototype.restore = function() {this.content.value = getCookie(this.id);};    //继承方法function extend(subClass, superClass) {var F = function() {};F.prototype = superClass.prototype;subClass.prototype = new F();subClass.prototype.constructor = subClass;subClass.superclass = superClass.prototype;if (superClass.prototype.constructor == Object.prototype.constructor) {superClass.prototype.constructor = superClass;}}    //输入框var InputField = function(id, label) {Field.call(this, id);this.input = document.createElement('input');this.content = this.input;this.label = document.createElement('label');var labelTextNode = document.createTextNode(label);this.label.appendChild(labelTextNode);this.element = document.createElement('div');this.element.id = id;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;};    //文本框var TextareaField = function(id, label) {Field.call(this, id);this.textarea = document.createElement('textarea');this.content = this.textarea;this.label = document.createElement('label');var labelTextNode = document.createTextNode(label);this.label.appendChild(labelTextNode);this.element = document.createElement('div');this.element.id = id;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;};    //选择框var SelectField = function(id, label) {Field.call(this, id);this.select = document.createElement('select');this.select.options.add(new Option("sfs", "sfs"));this.select.options.add(new Option("111", "2222222222")); //这边value会改变this.content = this.select;this.label = document.createElement('label');var labelTextNode = document.createTextNode(label);this.label.appendChild(labelTextNode);this.element = document.createElement('div');this.element.id = id;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.options.selectedIndex].value;};    //表单域var CompositeFieldset = function(id, legendText) {this.components = {};this.element = document.createElement('fieldset');this.element.id = id;if (legendText) {this.legend = document.createElement('legend');this.legend.appendChild(document.createTextNode(legendText));this.element.appendChild(this.legend);}};CompositeFieldset.prototype.add = function(child) {this.components[child.getElement().id] = child;this.element.appendChild(child.getElement());};CompositeFieldset.prototype.remove = function(child) {delete this.components[child.getElement().id];};CompositeFieldset.prototype.getChild = function(id) {if (this.components[id] != undefined) {return this.components[id];} else {return null;}};CompositeFieldset.prototype.save = function() {for ( var id in this.components) {if (!this.components.hasOwnProperty(id))continue;this.components[id].save();}};CompositeFieldset.prototype.restore = function() {for ( var id in this.components) {if (!this.components.hasOwnProperty(id))continue;this.components[id].restore();}};CompositeFieldset.prototype.getElement = function() {return this.element;};//组合模式开始/*  var contactForm=new CompositeForm('contact-form','POST','test'); 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')); var stateArray=[]; contactForm.add(new SelectField('state','State',stateArray)); contactForm.add(new InputField('zip','Zip')); contactForm.add(new TextareaField('comments','Comments')); contactForm.save(); */    //用组合模式汇合起来var contactForm = new CompositeForm('contact-form', 'POST', 'test');var nameFieldset = new CompositeFieldset('name-fieldset');nameFieldset.add(new InputField('first-name', 'First Name'));nameFieldset.add(new InputField('last-name', 'Last Name'));contactForm.add(nameFieldset);var addressFieldset = new CompositeFieldset('address-fieldset');addressFieldset.add(new InputField('address', 'Address'));addressFieldset.add(new InputField('city', 'City'));addressFieldset.add(new SelectField('state', 'State'));addressFieldset.add(new InputField('zip', 'Zip'));contactForm.add(addressFieldset);contactForm.add(new TextareaField('comments', 'Comments'));document.body.appendChild(contactForm.getElement());function a() {contactForm.save();}function b() {contactForm.restore();}//图片库var DynamicGallery=function(id){this.children=[];this.element=document.createElement('div');this.element.id=id;this.element.className='dynamic-gallery';};DynamicGallery.prototype={add:function(child){this.children.push(child);this.element.appendChild(child.getElement());},remove:function(child){for(var node,i=0;node=this.getChild(i);i++){if(node==child){this.children.splice(i,1);break;}}this.element.removeChild(chld.getElement());},getChild:function(i){return this.children[i];},hide:function(){for(var i=0,node;node=this.getChild(i);i++){node.hide();}this.element.style.display='none';},show:function(){this.element.style.display='block';for(var i=0,node;node=this.getChild(i);i++){node.show();}},getElement:function(){return this.element;}};//单个图片var GalleryImage=function(src){this.element=document.createElement('img');this.element.className='gallery-image';this.element.src=src;};GalleryImage.prototype={add:function(){},remove:function(){},getChild:function(){},hide:function(){this.element.style.display='none';},show:function(){this.element.style.display='';},getElement:function(){return this.element;}};//汇合起来var topGallery=new DynamicGallery('top-gallery');topGallery.add(new GalleryImage('img/abc1.jpg'));topGallery.add(new GalleryImage('img/abc2.jpg'));topGallery.add(new GalleryImage('img/abc3.jpg'));var vacationPhotos=new DynamicGallery('vacation-photos');for(var p=0;p<30;p++){vacationPhotos.add(new GalleryImage('img/abc3.jpg'));}topGallery.add(vacationPhotos);document.body.appendChild(topGallery.getElement());function c(){topGallery.hide();}function d(){topGallery.show();}</script></html>
组合模式通过简单的操作就能达到复杂的效果,一个操作通过遍历递归传递这个操作。不过组合模式的弱点也在于此,如果层次过多,则性能将受到影响。

组合模式应用场所  应用在对一批对象具有相同的动作的情况下适用,并产生递归的条件下。即是符合两个条件,一是产生递归,二是具有相同的动作。



原创粉丝点击