模式代码javaScript设计模式探究【3】

本文探讨了JavaScript中的单体模式及其应用场景,并提供了详细的代码示例。此外,还介绍了如何使用类式继承实现编辑器的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题记:写这篇博客要主是加深自己对模式代码的认识和总结实现算法时的一些验经和训教,如果有错误请指出,万分感谢。

       就上一篇所说的,按道理应当先说说用三种方式(类式继承、原型式继承、掺元式继承)分离实现edit-in-place。懒得敲代码了,所以就用最常用的类式继承实现。其余两种方法就先不说了,如果大家都想看到的话,那我再修改,贴出来吧。最近需要准备练习,完善简历,大巷网上得填写简历去,不知道博客园里头是否会有猎头看到这篇文章,那顺便宣扬一下,大巷网-搜索-哈尔滨工业大学-刘平,就能够找到我,如果大家有好的练习单位,也可以给我私信。

模式和代码 模式和代码 View Code
/**
 * @author tonylp
 */
function EditInPlaceField(id,parent,value){
    this.id = id;
    this.parentElement = parent;
    this.value = value || 'default value';
    
    this.createElements(this.id);
    this.attachEvents();
};

EditInPlaceField.prototype = {
    createElements:function(id){
        this.containerElement = document.createElement('div');
        this.parentElement.appendChild(this.containerElement);
        
        this.staticElement = document.createElement('span');
        this.containerElement.appendChild(this.staticElement);
        this.staticElement.innerHTML = this.value;
        
        this.fieldElement = document.createElement('input');
        this.fieldElement.type = 'text';
        this.fieldElement.value = this.value;
        this.containerElement.appendChild(this.fieldElement);
        
        this.saveButton = document.createElement('input');
        this.saveButton.type = 'button';
        this.saveButton.value = 'Save';
        this.containerElement.appendChild(this.saveButton);
        
        this.cancelButton = document.createElement('input');
        this.cancelButton.type = 'button';
        this.cancelButton.value = 'Cancel';
        this.containerElement.appendChild(this.cancelButton);
        this.convertToText();
    },
    attachEvents:function(){
        var that = this;
        addEvent(this.staticElement,'click',function(){that.convertToEditable();});
        addEvent(this.saveButton,'click',function(){that.save();});
        addEvent(this.cancelButton,'click',function(){that.cancel();});
    },
    convertToEditable:function(){
        this.staticElement.style.display = 'none';
        this.fieldElement.style.display = 'inline';
        this.saveButton.style.display = 'inline';
        this.cancelButton.style.display = 'inline';
        
        this.setValue(this.value);
    },
    save:function(){
        this.value = this.getValue();
        var that = this;
        var callback = {
            success:function(){that.convertToText();},
            failure:function(){alert('Error saving value.');}
        };
        ajaxRequest('get','save.php?id='+this.id+'&value='+this.value,callback);
    },
    cancel:function(){
        this.convertToText();
    },
    convertToText:function(){
        this.fieldElement.style.display = 'none';
        this.saveButton.style.display = 'none';
        this.cancelButton.style.display = 'none';
        this.staticElement.style.display = 'inline';
        
        this.setValue(this.value);
    },
    
    setValue:function(value){
        this.fieldElement.value = value;
        this.staticElement.innerHTML = value;
    },
    getValue:function(){
        return this.fieldElement.value;
    }
};

//要创立一个就地编辑域,只需要实例化这个类即可
var titleClassical = new EditInPlaceField('titleClassical',$('doc'),'Title Here');
var currentTitleText = titleClassical.getValue();

//接下来我们要创立一个使用多行文本框而不是单行文本框的类,这个EditInPlaceArea类,这个类继承了EditInPlaceField
function EditInPlaceArea(id,parent,value){
    EditInPlaceArea.superclass.constructor.call(this,id,parent,value);
};
extend(EditInPlaceArea,EditInPlaceField);
EditInPlaceArea.prototype.createElements = function(id){
        this.containerElement = document.createElement('div');
        this.parentElement.appendChild(this.containerElement);
        
        this.staticElement = document.createElement('p');
        this.containerElement.appendChild(this.staticElement);
        this.staticElement.innerHTML = this.value;
        
        this.fieldElement = document.createElement('textarea');
        this.fieldElement.type = 'text';
        this.fieldElement.value = this.value;
        this.containerElement.appendChild(this.fieldElement);
        
        this.saveButton = document.createElement('input');
        this.saveButton.type = 'button';
        this.saveButton.value = 'Save';
        this.containerElement.appendChild(this.saveButton);
        
        this.cancelButton = document.createElement('input');
        this.cancelButton.type = 'button';
        this.cancelButton.value = 'Cancel';
        this.containerElement.appendChild(this.cancelButton);
        this.convertToText();
};
EditInPlaceArea.prototype.convertToEditable = function(){
        this.staticElement.style.display = 'none';
        this.fieldElement.style.display = 'block';
        this.saveButton.style.display = 'inline';
        this.cancelButton.style.display = 'inline';
        
        this.setValue(this.value);
}
EditInPlaceArea.prototype.convertToText = function(){
        this.staticElement.style.display = 'block';
        this.fieldElement.style.display = 'block';
        this.saveButton.style.display = 'none';
        this.cancelButton.style.display = 'none';
        
        this.setValue(this.value);
}
    每日一道理
成功的花朵开放在啊勤劳的枝头,失败的苦果孕育在懒惰的温床之中。
      好了,可以进入正题了,到现在为止都还没有讲过一种特定的设计模式,那么接下来就重点探究一下这几种模式。这里一共会有 单体模式、工厂模式、桥接模式、组合模式、门面模式、适配器模式、装饰者模式、享元模式、代理模式、观察者模式、命令模式、职责链模式12种模式。看情况不知道能说几种,按我的懂得来讲几种,如果没说完,大家可以去看看汤姆大叔的博客,我发现我现在成了他博客的倾销者了。。额。。略有打广告之嫌。

     1.1 单体模式--javascript中最基本又最有用的模式之一

     通过确保单体对象只存在一份实例,你就能够确信自己的所有代码使用的都是一样的全局资源

     用途:划分命名空间,增加网页中全局变量的数目,利用分支技术来封装浏览器之间的差异,组织代码,模块化。

     单体模式基本结构

模式和代码 模式和代码 View Code
var Signleton = {
    attribute1:true,
    attribute2:10,
    method1:function(){
        
    },
    method2:function(){
        
    }
};
   单体对象由两部分组成:包含着方法和属性成员的对象自身,以及用于拜访它的变量。这个变量通常是全局性的。

   1.2 划分命名空间

模式和代码 模式和代码 View Code
// GiantGorp namespace
var GiantGorp = {};
GiantGorp.Common ={
    // a signleton with common methods used by all objects and modules
};
GiantGorp.ErrorCodes = {
    // An object literal used to store data.
};

GiantGorp.PageHandler = {
    // a signleton with page specific methods and attributes.
};
    其实最好的学习方法是去看一个javascript的开源框架或是开源插件,例如jquery,dataTables,里头会有很多命名空间和私有方法,公然方法,你就能够研讨它们。

  1.3 用作特定网页专用代码的包装器的单体

    在具有很多网页的网站中,有些javascript代码是所有网页都要用到的,它们通常被存放在独立的文件中;而有些代码则是某个网页专用品德,不会被用到其他地方。下面是用来包装特定网页专用代码的单体的骨架:

模式和代码 模式和代码 View Code
Namespace.PageName = {
    
    //Page Constants
    CONSTANT_1:true,
    CONSTANT_2:10,
    
    //Page methods
    method1:function(){
        
    },
    method2:function(){
        
    },
    //Initialization method.
    init:function(){
        
    }
}
addLoadEvent(Namespace.PageName.init);
  1.4 具有私有成员的单体

       如果大家还记得话,在javascript设计模式探究【1】中,我就讲过用两种方法实现私有成员,下面给出一段模块模式代码(module pattern)--指的是它可以把一批相关方法和属性组织委模块并起到划分命名空间的作用。

模式和代码 模式和代码 View Code
MyNamespace.singleton =(function(){
    //private member.
    var privateAttribute1 = false;
    var privateAttribute2 = [1,2,3];
    function privateMethod1(){
        ...
    }
    function privateMethod2(){
        ...
    }
    return {
        publicAttribute1:true,
        publicAttribute2:10,
        
        publicMethod1:function(){
            ...
        },
        publicMethod2:function(){
            ...
        }
    }
})();
  1.5 惰性实例化--将实例化推迟到需要使用它的时候,惰性加载,常用于那些加载大量数据的单体。
模式和代码 模式和代码 View Code
MyNamespace.singleton =(function(){
    var uniqueInstance;
    function constructor(){
        //private member.
        var privateAttribute1 = false;
        var privateAttribute2 = [1,2,3];
        function privateMethod1(){
            ...
        }
        function privateMethod2(){
            ...
        }
        return {
            publicAttribute1:true,
            publicAttribute2:10,
            
            publicMethod1:function(){
                ...
            },
            publicMethod2:function(){
                ...
            }
        }
    }
    return {
        getInstance:function(){
            if(!uniqueInstance){
                uniqueInstance = constructor();
            }
            return uniqueInstance;
        }
    }
})();
   细心比拟一下1.4中的代码和1.5中的代码的区分

   说明:惰性加载单体的特别之处在于:对它们的拜访必须借助于一个静态方法,应当这样调用其方法:Singleton.getInstance().methodName();getInstance方法会检查该单体是否已被实例化了。惰性加载单体的缺点是其代码复杂。

 1.6 分支--用来把浏览器间的差异封装到运行期间停止设置的动态方法中的技术。

模式和代码 模式和代码 View Code
MyNamespace.singleton =(function(){
    var objectA ={
        method1:function(){
            
        }
        method2:function(){
            
        }
    }
    var objectB ={
        method1:function(){
            
        }
        method2:function(){
            
        }
    }
    return (someCondition)?objectA:objectB;
})();
    上述代码中创立了两个对象字面量,它们具有相同的一套方法,通过条件检测,确保运行的代码是该javascript环境下所需要的特性。

     分支技术其实不总是更高效的选择,后面的例子中,有两个对象被创立出来并保存在内存中,但是派上用场的只有一个。

  1.7 总结

            从为代码提供命名空间和增强器模块化的角度考虑,你应当尽量多的使用单体模式,尤其是在网页中包含着形形色色的javascript代码来源。分支技术可以创立高效的方法,不需要管浏览器的兼容性。单体模式提供一种单点拜访,所以它有可能致使模块的强耦合,而且也不利于单元测试。单体模式是一个基本,为后面的各种模式的一个基本。

     以上全部都属个人原创,请大家转载的时候附上原创链接: http://www.cnblogs.com/tonylp

文章结束给大家分享下程序员的一些笑话语录: IT业众生相
第一级:神人,天资过人而又是技术狂热者同时还拥有过人的商业头脑,高瞻远瞩,技术过人,大器也。如丁磊,求伯君。
第二级:高人,有天赋,技术过人但没有过人的商业头脑,通常此类人不是顶尖黑客就是技术总监之流。
第三级:牛人,技术精湛,熟悉行业知识,敢于创新,有自己的公司和软件产品。
第四级:工头,技术精湛,有领导团队的能力,此类人大公司项目经理居多。
第五级:技术工人,技术精湛,熟悉行业知识但领导能力欠加,此类人大多为系分人员或资深程序员,基本上桀骜不逊,自视清高,不愿于一般技术人员为伍,在论坛上基本以高手面目出现。
第六级:熟练工人,技术有广度无深度,喜欢钻研但浅尝辄止。此类人大多为老程序员,其中一部分喜欢利用工具去查找网上有漏洞的服务器,干点坏事以获取成绩感。如果心情好,在论坛上他们会回答菜鸟的大部分问题。此级别为软件业苦力的重要组成部分。
第七级:工人,某些技术较熟练但缺乏深度和广度,此类人大多为程序员级别,经常在论坛上提问偶尔也回答菜鸟的问题。为软件产业苦力的主要组成部分。
第八级:菜鸟,入门时间不长,在论坛上会反复提问很初级的问题,有一种唐僧的精神。虽然招人烦但基本很可爱。只要认真钻研,一两年后就能升级到上一层。
第九级:大忽悠,利用中国教育的弊病,顶着一顶高学历的帽子,在小公司里混个软件部经理,设计不行,代码不行,只会胡乱支配下属,拍领导马屁,在领导面前胡吹海侃,把自己打扮成技术高手的模样。把勾心斗角的办公室文化引入技术部门,实在龌龊!
第十级:驴或傻X,会写SELECT语句就说自己精通ORALCE,连寄存器有几种都不知道就说自己懂汇编,建议全部送到日本当IT产业工人,挣了日本人的钱还严重打击日本的软件业!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值