文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>无聊+蛋疼, 试试用javascript怎样实现接口

无聊+蛋疼, 试试用javascript怎样实现接口

时间:2010-08-27  来源:undefined

今天, 当当的书到了, 《javascript设计模式》。

刚刚翻了下, 上来就大谈特谈接口。

提到:javascript本身不支持接口, 所以有三种方法可以实现接口。

第一种是掩耳盗铃式的, 在类前面写注释:me要实现these方法, 请不要拦着我。。。

- -!

第二种是做属性检查。看的晕晕的。 似乎是, 写代码查, 你对不对?不对给我出局。

=。=

第三种是鸭子检查。说到底还是检查。 只不过放到类里面检查去了。 不全部实现, 连new都不行。

啊, 这下严格了。^_^

 

作者喜欢第三者(。。。。 表误会, 就是第三个的意思)。 我则喜欢第二者。

作者说第二个不好, 我琢磨着挺好的啊。

 

正好时间比较空, 我就试着写了一段检查程序用来查接口玩。

 

因为这不是在干什么好事, 所以我给对象命名为:

EvilJSLib

 

啊, 首先写了一堆定义接口和类的东东。

所以就是:

EvilJSLib.js

 

代码 (function(window, undefined){

    var IInterFace = function(interfaceName){
        this.interfaceDetail = {};
        this.interfaceDetail.interfaceName = interfaceName;
        this.interfaceDetail.properties = [];
        this.interfaceDetail.methods = [];
    };
    var IClass = function(className){
        this.classDetail = {};
        this.classDetail.className = className;
        this.classDetail.InterFaces = [];
    };
    IInterFace.prototype.AddProperty = function(name){
        this.interfaceDetail.properties.push(name);
        return this;
    }
    IInterFace.prototype.AddMethod = function(name){
        this.interfaceDetail.methods.push(name);
        return this;
    }
    IClass.prototype.implement = function(InterFace){
        this.classDetail.InterFaces.push(InterFace);
    }
    
    var EvilJSLib = {
        NameValuePair: function(){
            this.name = '';
            this.value = '';
        },
        CreateInterface: function(name){
            return new IInterFace(name);
        },
        CreateClass: function(name){
            return new IClass(name);
        }
    };
    
    window.EvilJSLib = EvilJSLib;
})(window);


 然后impletement就成了方法, 这样就避免了没有这个关键字的问题了。。。。

 

然后呢,  我写了个检查程序。 为了让这段小小的程序给自己强大的满足感, 我用了个很夸张的词:

compile!

当然了, 其实只是检查是不是所有的属性都实现了。

- -!

 

JSCompiler.js

代码 (function(window, undefined){
    
    var jsCompiler = {
        ErrorCodes: {
            '0x01': {
                name: 'ClassNotImeplement',
                detail: 'The Class is not Imeplement'
            },
            '0x02': {
                name: 'PropertyNotDefined',
                detail: 'The Property is not Imeplement'
            },
            '0x03': {
                name: 'MethodNotDefined',
                detail: 'The method is not Imeplement'
            }
        },
        OutPutError: function(ErrorCode, ClassName, subNameType, subName){
            var currentError = jsCompiler.ErrorCodes[ErrorCode];
            document.writeln('ErrorCode:' + ErrorCode);
            document.writeln('<br />');
            document.writeln('\tname:' + currentError.name);
            document.writeln('<br />');
            document.writeln('\tdetail:' + currentError.detail);
            document.writeln('<br />');
            document.writeln('\tClass Name:' + ClassName);
            document.writeln('<br />');
            document.writeln('\t' + subNameType + ' Name:' + subName);
            document.writeln('<br /><br />');
        },
        
        ValidateAllInterfaceImplemented: function(Class, Interface){
            document.write('<hr />');
            for (var i = 0, length = Interface.interfaceDetail.properties.length; i < length; i++) {
                var currentItemName = Interface.interfaceDetail.properties[i];
                if(!Class.propertyIsEnumerable(currentItemName) || typeof Class[currentItemname] == 'function'){
                    jsCompiler.OutPutError('0x02', Class.classDetail.className,'Property',currentItemName);
                }
            }
            for (var i = 0, length = Interface.interfaceDetail.methods.length; i < length; i++) {
                var currentItemName = Interface.interfaceDetail.methods[i];
                if(!Class.propertyIsEnumerable(currentItemName) || typeof Class[currentItemname] != 'function'){
                    jsCompiler.OutPutError('0x03', Class.classDetail.className,'Method',currentItemName);
                }
            }
            
            document.write('<hr />');
        },
        compile: function(Class){
            for (var i = 0, length = Class.classDetail.InterFaces.length; i < length; i++) {
                jsCompiler.ValidateAllInterfaceImplemented(Class, Class.classDetail.InterFaces[i]);
            }
        },
        compileAll: function(classes){
            for (var i = 0, length = classes.length; i < length; i++) {
                jsCompiler.compile(classes[i]);
            }
        },
    };
    window.EvilJSLib.jsCompiler = jsCompiler;
})(window);


 

 然后就是使用了。

我试着写了这么个文件来测试下EvilJSLib:

 

 TestEvilJsLib.js

 

代码 (function(EvilJSLib){
    var TestEvilJSLib = {};
    var IList = EvilJSLib.CreateInterface('IList');
    IList.AddProperty('name').AddProperty('age').AddMethod('printname');
    TestEvilJSLib.IList = IList;
    
    var List = EvilJSLib.CreateClass('List');
    List.implement(IList);
    TestEvilJSLib.List = List;
    window.TestEvilJSLib = TestEvilJSLib;
})(window.EvilJSLib);


这样呢, 我们创建了一个接口, 叫IList, 创建了一个对象叫List, 实现了接口, 但是什么都没写。

毫无疑问, 这是不允许的, 这要是C#, 编译错误都够装满整个外滩了。

 

那么如何知道这些问题呢?

当然了, 调用我们的编译器吗!

 

 简单的这样:

 

代码 <html>
    <head>
        <title>only debug</title>
        <script type="text/javascript" src="lib/EvilJSLib.js"></script>
        <script type="text/javascript" src="lib/TestEvilJSLib.js"></script>
        <script type="text/javascript" src="lib/JSCompiler.js"></script>
        <script type="text/javascript">
            window.EvilJSLib.jsCompiler.compile(window.TestEvilJSLib.List);
        </script>
    </head>
</html>


 OK, 运行出来了一个看起来很威武的结果:

ErrorCode:0x02
name:PropertyNotDefined
detail:The Property is not Imeplement
Class Name:List
Property Name:name

ErrorCode:0x02
name:PropertyNotDefined
detail:The Property is not Imeplement
Class Name:List
Property Name:age

ErrorCode:0x03
name:MethodNotDefined
detail:The method is not Imeplement
Class Name:List
Method Name:printname

 

 嘿嘿, 这下就可以一目了然哪些类实现了接口但是没有完成方法了。

至于这样做有什么好处。。。 这个, 大概可以模拟一些设计模式吧。 策略模式毫无疑问是没问题的。 因为对于js来说, 同名的方法, 就是同一个方法。。 用名字调的, 一定是最终实现的。

 

如果有继承怎么办? 不是有prototype来处理么。 一层一层跌落。 自然会运行的很好的。

 

声明:这本来就是一篇蛋疼的文章, 只用于娱乐, 严禁正式使用。

最后我想说:在你进来读这篇文章的第一个字的时候,你就上当了。。。。。

而且我必须黑幕掉沙发。

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载