程劭非ID:dead_of_winter
17225次访问,排名6755(-1)好友2人,关注者5
from ATC
dead_of_winter的文章
原创 41 篇
翻译 1 篇
转载 13 篇
评论 21 篇
最近评论
dead_of_winter:prototype只是特定时代的东西 几个极其稀有的“高手”把自己的公共代码分享出来给大家用 根本说不上是框架
prototype只用了一行代码 就能让我们这些程序员彻底对它绝望:
RegExp.prototype.match = RegExp.prototype.test;
mackyliu:显然选用框架的人大多数只是应用者,对于许多真正的开发者来说,可能更多的只是选用各个框架里比较优秀的一小段代码而已,prototype的确"污染了"许多对象,但使用者似乎也根本不需要去考虑对象的实质应用处理过程,有好的类来替代一个相对复杂的处理过程,无疑是菜鸟们的一大福音。然而对于我们搞程序的人来说,可能更多的会去关注一个框架的扩展性
dead_of_winter:hoho 不是这样的 QQ上详细说吧:)
BlueDestiny:循环引用是三者之间(或三者以上)的相互引用,只用切断其一就可以了
<html>
<head>
<script language="JScript">

var myGlobalObject;

function SetupLeak()
{
// First……
dead_of_winter:我不怀疑prototype作者的水平 不过它写得实在太随意了 不像是写框架的态度
还有啊 pt该补习下OO基础知识了 Insertion这种东西最好就别出现了- -#
YUI有多好先不说 起码这些基本的地方做得不错
文章分类
收藏
    相册
    贴图
    ACM
    哈尔滨工程大学ACM
    .net framework3.0
    中国科技大学ACM
    俄罗斯乌拉尔大学ACM......
    北京大学ACM
    吉林大学ACM(故障?)
    同济大学ACM
    哈尔滨工业大学ACM
    四川大学ACM
    天津大学ACM
    暨南大学珠海学院ACM
    杭州电子科技大学ACM
    汕头大学ACM
    浙江大学ACM
    CSDN BLOGS
    50米深蓝
    chenhu_doc
    一刀流
    小三
    搜索如风
    程化
    雁南飞
    泡的bbs
    无忧脚本
    资源
    WindowsAPI参考
    wpf(RSS)
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 JavaScript设计模式交流(三)——Templete Method Pattern 收藏

    新一篇: javascript设计模式交流(五) ——Composite Pattern | 旧一篇: javascript设计模式交流(四) ——Interpreter Pattern

        Templete Method是一个相对简单的模式,在父类中一个 多态地调用子类方法的方法 被称为Templete Method,在js中,因为缺少必要的接口检查和虚方法,不能够简单地使用C++或者Java的方式实现,但通过js的scope chain的灵活应用,可以更为优美地实现这一模式。
        在js中,有一种非常有趣的继承方式:元类。尽管语言级别未提供支持,但是first class的函数和动态语言特性使得js能更为彻底地实现元类继承。首先,大概介绍下下元类继承的方式:

    Code:

    function parent(string){
        var 
    child=new Function("this.x=10;"+string);
        return 
    child;
    }
    var 
    child=new parent("this.y=20;");

    var 
    childObj=new child();
    alert(childObj.y); 


    以某种方式创建一个函数,并将之返回,这就是js版的元类继承。作为扩展,可以不使用Function创建函数,parent为子类提供参数

    Code:

    function parent(n){    
        return function(){
            
    this.show=function(){
                 
    alert(n);
            }
        };
    }
    var 
    child=new parent(20);

    var 
    childObj=new child();
    childObj.show(); 


    如果你认为这不能算作继承的话,那么下面一段代码可以展现这种继承的灵活性:

    Code:

    function parent(prototype){
        return function(){
            
    this.show=function(){
                 
    alert("show");
            }
            for(var 
    p in prototype)this[p]=prototype[p];
        };



    这是一个类似原型继承的元类 且它可指定不论以什么对象为原型,创建的类都至少有一个可覆盖的show方法。如果调换一下顺序,则可变成,不论如何,都会有不可覆盖的show方法,原型当中的show方法会被忽略:

    Code:

    function parent(prototype){
        return function(){
            for(var 
    p in o)this[p]=prototype[p];
            
    this.show=function(){
                 
    alert("show");
            }
        };



    实际上到此为止,Templete Method的实现方法已经是显然的了,将Templete Method需要用到的方法作为参数传递给元类,将Templete Method放在上例的show的位置即可。下面给出一个广度优先搜索的例子:(以后也许还会用它做策略模式的组成部分 hoho)

    Code:

    function BreadthFirstSearch(extend,beam,finish)
    {
        return function(){
            
    this.finish=finish;
            
    this.extend=extend;
            
    this.beam=beam
            
    this.search=function(){
                
                var 
    queue=[this];
                while(
    queue.length)
                {
                    var 
    current=queue.shift();
                    if(!
    current.beam()){
                        var 
    extended=current.extend();
                        for(var 
    i=0;i<extended.length;i++)
                        {
                            if(
    extended[i].finish())return extended[i];
                            
    queue.push(extended[i]);
                        }
                    }        
                }
                return 
    null;
            }
        }



    按照广搜的算法extend返回一个数组,包含当前节点扩展出的所有子节点,beam是剪枝函数,它返回true表示当前节点可被剪除,否则该节点将被扩展,finish检查是否已搜索到最终结果,如果是则返回true则结束整个搜索。

    这个例子过于抽象,我自己看起来都有些不知所云,所以我决定免费赠送一个用此搜索算法解决八皇后问题的例子的例子:P
    首先定义八皇后问题的数据结构,用最传统的类和对象来解决:

    Code:

    function Queen(n){
        var 
    ret=new Array();
        var 
    depth=0;
        for(var 
    y=0;y<n;y++)
        {
            
    ret.push([]);
            for(var 
    x=0;x<n;x++)
                
    ret[ret.length-1].push(0);
        }



    广搜算法是一个泛型算法,所以我们还可以把它设计成一个Prototype Patten,通过定义clone方法来使它不依赖具体类型,这里算是补充一个Prototype Patten的例子,综合使用的clone函数将大大提高clone的速度,我把这种clone方式称为"深原型clone",它的开销比创建深clone对象小得多,且对clone体的修改不会影响到母体和其他clone体,但母体的修改会影响到所有clone体,为了调试方便,我们还可以定义一个toString显示美观一点的棋盘结构,ok,下面是完整的数据结构

    Code:

    <script>
    function 
    Queen(n){
        var 
    ret=new Array();
        
    ret.size=n;
        
    ret.depth=0;//搜索的深度
        
    ret.pos=0;//新皇后的水平位置
        
    for(var y=0;y<n;y++)
        {
            
    ret.push([]);
            for(var 
    x=0;x<n;x++)
                
    ret[ret.length-1].push(0);
        }
        function 
    objectPrototypeClone()
        {
            var 
    tmp=function(){};
            
    tmp.prototype=this;
            return new 
    tmp;
        }
        
    ret.clone=function(){
            var 
    r=objectPrototypeClone.call(this);
            for(var 
    i=0;i<n;i++)
            {
                
    r[i]=objectPrototypeClone.call(this[i])
            }
            return 
    r;
        }
        
    ret.toString=function(){
            var 
    str="";
            for(var 
    y=0;y<n;y++)
            {
                for(var 
    x=0;x<n;x++)
                    
    str+=this[y][x]==0?"○":"★";
                
    str+="\n";
            }
            return 
    str;
        }
        return 
    ret;
    }
    </script> 


    接下来进入正题,写出八皇后问题的extend beam finish三个函数

    extend函数非常容易,八皇后问题每层搜索一行,extend函数即扩展一个新行

    Code:

    function extendQueen()
    {
        var 
    ret=new Array();
        
    //alert(this.depth);
        
    for(var i=0;i<this.size;i++)
        {
            var 
    current=this.clone();
            
    //alert(current.depth);
            
    current[current.depth][i]=1;
            
    current.pos=i;
            
    current.depth++;
            
    ret.push(current);
        }
        return 
    ret;



    beam函数则是检查新的皇后能否吃到以前的皇后

    Code:

    function beamQueen()
    {
        var 
    x,y;
        if(
    this.depth==0)return false;
        if(
    this.depth==this.size)return true;
        
    x=this.pos;y=this.depth-1;
        while(--
    x>=0&&--y>=0)
            if(
    this[y][x]!=0)return true;

        
    x=this.pos;y=this.depth-1;
        while(--
    y>=0)
            if(
    this[y][x]!=0)return true;

        
    x=this.pos;y=this.depth-1;
        while(--
    y>=0&&++x<this.size)
        {
            if(
    this[y][x]!=0)return true;
        }
        return 
    false;



    最后是finish函数 在beam的基础上修改一下就可以了 我们可以通过finish检查,来决定求一个可行解、求所有解、还是对解计数,下面的finish是求出并打印所有解。

    Code:

    function finishQueen(){
        if(
    this.depth<this.size)return false;
        
    x=this.pos;y=this.depth-1;
        while(--
    x>=0&&--y>=0)
            if(
    this[y][x]!=0)return false;

        
    x=this.pos;y=this.depth-1;
        while(--
    y>=0)
            if(
    this[y][x]!=0)return false;

        
    x=this.pos;y=this.depth-1;
        while(--
    y>=0&&++x<this.size)
        {
            if(
    this[y][x]!=0)return false;
        }

        
    document.write(this+"\n");
        return 
    false;



    有了这三个函数之后,就可以定义一个BFSQueen类,使它继承Queen类并实现BreadthFirstSearch接口
    定义如下

    Code:

    function BFSQueen(n)
    {
        var 
    ret=new Queen(n);
        var 
    BFS=new BreadthFirstSearch(extendQueen,beamQueen,finishQueen);
        
    BFS.apply(ret);
        return 
    ret;



    下面是完整的八皇后问题代码,在我的电脑上大约跑了30秒 用FF的话只需要一半的时间
    <pre style="font-family:宋体;">
    <script>
    function Queen(n){
        
    var ret=new Array();
        ret.size
    =n;                                //皇后问题的规模
        ret.depth=0;                                //搜索的深度
        ret.pos=0;                                //新皇后的水平位置
        for(var y=0;y<n;y++)
        {
            ret.push([]);
            
    for(var x=0;x<n;x++)
                ret[ret.length
    -1].push(0);
        }
        
    function objectPrototypeClone()
        {
            
    var tmp=function(){};
            tmp.prototype
    =this;
            
    return new tmp;
        }
        ret.clone
    =function(){
            
    var r=objectPrototypeClone.call(this);
            
    for(var i=0;i<n;i++)
            {
                r[i]
    =objectPrototypeClone.call(this[i])
            }
            
    return r;
        }
        ret.toString
    =function(){
            
    var str="";
            
    for(var y=0;y<n;y++)
            {
                
    for(var x=0;x<n;x++)
                    str
    +=this[y][x]==0?"":"";
                str
    +=" ";
            }
            
    return str;
        }
        
    return ret;
    }

    function extendQueen()
    {
        
    var ret=new Array();
        
    if(this.depth==this.size)return ret;
        
    for(var i=0;i<this.size;i++)
        {
            
    var current=this.clone();
            
    //alert(current.depth);
            current[current.depth][i]=1;
            current.pos
    =i;
            current.depth
    ++;
            ret.push(current);
        }
        
    return ret;
    }
    function beamQueen()
    {
        
    var x,y;
        
    if(this.depth==0)return false;
        
    if(this.depth==this.size)return true;
        x
    =this.pos;y=this.depth-1;
        
    while(--x>=0&&--y>=0)
            
    if(this[y][x]!=0)return true;

        x
    =this.pos;y=this.depth-1;
        
    while(--y>=0)
            
    if(this[y][x]!=0)return true;

        x
    =this.pos;y=this.depth-1;
        
    while(--y>=0&&++x<this.size)
        {
            
    if(this[y][x]!=0)return true;
        }
        
    return false;
    }

    function finishQueen(){

        
    if(this.depth<this.size)return false;
        x
    =this.pos;y=this.depth-1;
        
    while(--x>=0&&--y>=0)
            
    if(this[y][x]!=0)return false;

        x
    =this.pos;y=this.depth-1;
        
    while(--y>=0)
            
    if(this[y][x]!=0)return false;

        x
    =this.pos;y=this.depth-1;
        
    while(--y>=0&&++x<this.size)
        {
            
    if(this[y][x]!=0)return false;
        }

        document.write(
    ++count+". "+this);
        
    return false;
    }
    function BreadthFirstSearch(extend,beam,finish)
    {
        
    return function(){
            
    this.finish=finish;
            
    this.extend=extend;
            
    this.beam=beam; 
            
    this.search=function(){
                
                
    var queue=[this];
                
    while(queue.length)
                {
                    
    var current=queue.shift();
                    
    if(!current.beam()){
                        
    var extended=current.extend();
                        
    for(var i=0;i<extended.length;i++)
                        {
                            
    if(extended[i].finish())return extended[i];
                            queue.push(extended[i]);
                        }
                    }        
                }
                
    return null;
            }
        }
    }
    function BFSQueen(n)
    {
        
    var ret=new Queen(n);
        
    var BFS=new BreadthFirstSearch(extendQueen,beamQueen,finishQueen);
        BFS.apply(ret);
        
    return ret;
    }
    var queen=new BFSQueen(8);
    var count=0;
    queen.search();
    </script>
    </pre>


    附:八皇后问题
    八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
    高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。

    发表于 @ 2008年03月09日 11:19:00|评论(loading...)|编辑

    新一篇: javascript设计模式交流(五) ——Composite Pattern | 旧一篇: javascript设计模式交流(四) ——Interpreter Pattern

    评论:没有评论。

    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © 寒冬