dom Framework oop模块

此模块提供强大的面向对象编程能力,非常感谢mootools等先行者做出的有益探索,虽然现在我放出来的版本比最初的削减了许多功能,但依然非常强大。

 

/*dom Framework version 1.0

Copyright 2010

Dual licensed under the MIT or GPL Version 2 licenses.

author: <ruby> <rb>司徒正美<rp>(zhongqincheng)</rp></rb><rt>しとぅなさみ</rt></ruby>

http://www.cnblogs.com/rubylouvre/

*/

   //=========================================

    // OOP模块 提供强大的面向对象编程, ruby风格的继承机制

    //==========================================

    ;;;(function(dom,window,undefined){

        dom.provide("oop");



        var classMethods = (function() {

            var include = ["constructor"],

            extend  = 'prototype $supers $super extend include'.toArray();

            function cleanModule(module, array) {

                array = array == 'extend' ? extend : include

                for(var key in module){

                    if(module.hasOwnProperty(key) && array.contains(key)){

                        delete module[key]

                    }

                }

                return module;

            }

            return {

                //桥梁模式,将实现化与抽象化脱耦,便得两者可以独立地变化

                //http://javascript.crockford.com/prototypal.html

                inherit: function(parent) {

                    if (parent && parent.prototype) {

                        var bridge = function() {};

                        bridge.prototype = parent.prototype;

                        this.prototype = new bridge;

                        this.$super = parent;

                    }

                    this.$supers = [];//这里的this为类

                    while (parent) {

                        if(!dom.isPureObject(parent)){//父类不能为默认添加的Object

                            this.$supers.push(parent);

                            parent = parent.$super;

                        }

                    }

                    return this.prototype.constructor = this;

                },

                alias : function(oldName, newName){

                    var proto = this.prototype;

                    if (dom.isString(oldName)){

                        var method = proto[oldName]

                        method && (proto[newName] = method);

                    }else if(is(oldName,"Object")){

                        dom.each(oldName,function(neo,old){

                            this.alias(old,neo)

                        },this)

                    }

                    return this;

                },

                //为新类添加一些类成员

                extend: function() {

                    dom.toArray(arguments).each(function(module){

                        dom.mixin(this, cleanModule(module, 'extend'));

                    },this);

                    return this;

                },

                //为新类添加原型成员,如果它们是函数,则判断其与父类有没有同名方法,

                //有则改写当前类的成员,在它上面添加一个$super属性

                include: function() {

                    var $supers = this.$supers.pluck('prototype');

                    dom.slice(arguments).each(function(module){

                        cleanModule(module, 'include');//去除模块包中那些危险属性

                        dom.keys(module).each(function(key){

                            var value = module[key],isFn = dom.is(value,"Function");

                            if(key.startsWith("protected ")){

                                key = key.toArray()[1];

                                if(isFn){

                                    value._protected = true;

                                }

                            }

                            var parent = $supers.first(function(proto) {

                                return dom.is(proto[key],"Function");

                            });

                            this.prototype[key] = isFn ?

                            (function( method,  key, parent) {

                                return function() {

                                    parent && (this.$super = parent[key]);      

                                    if (method._protected && this._method == null){

                                        throw new Error('The method "' + key + '" is protected!');

                                    }

                                    this._method = arguments.callee;

                                    var result = method.apply(this, arguments);

                                    delete this._method;

                                    return result;

                                };

                            })(value,  key, parent) :value;

                            if(isFn){

                                this.prototype[key].toString = function(){

                                    return String(value);

                                }

                            }

                        },this);

                    },this);

                    return this;

                }

            }

        })();

        //第一类工厂

        //{inherit :superclass,include:instance_member,extend:class_member,singleton:boolean}

        dom.oop = function(obj){

            obj = obj || {};

            //新类的原始构造器

            var init = init || obj.init || dom.noop;

            delete obj.init;

            //父类

            var superclass = obj.inherit || Object;

            //判定是否需要实现单例

            var singleton  = !!obj.singleton ;

            delete obj.singleton;

            //------------------创建新类--------------------------------------------

            var klass = function() {

                if(singleton && klass.instance){//实现单例模式

                    return klass.instance

                }

                superclass.apply(this, arguments);

                init.apply(this, arguments);

                if(singleton)

                    klass.instance = this;

                return this;

            };

            //添加泛化成员与原型成员

            dom.mixin(klass, classMethods).inherit(superclass);

            ["extend", "include"].each(function(name) {

                if (obj[name]) {

                    var modules = dom.toArray(obj[name]);

                    klass[name].apply(klass, modules);

                    delete obj[name];

                }

            });

            var proto = klass.prototype;

            klass.include(obj);

            if(!proto.__proto__){//修复IE与Opera中的第二条原型链

                proto.__proto__ = proto

            }

            proto.$super = superclass;

            klass.toString = function(){//重写构造子的toString

                return init.toString();

            }

            return klass

        }

    })(window[escape(document.URL.split("#")[0])],this);



一些示例:

继承。


        var Animal = dom.oop({

          init: function(name) {

            this.name = name;

          },

          eat: function() {

            dom.console.log('yummie');

          }

        });





        var Human = dom.oop({

          inherit: Animal,//注意这里,使用inherit

          speak: function() {

            dom.console.log(this.name + ' said bla bla bla');

          }

        });



        var peter = new Human('peter');

        peter.eat();//yummie

        peter.speak();//peter said bla bla bla



        var Pat = dom.oop({

          inherit: Human,//注意这里,使用inherit

          init: function(name,age) {//注意这里name

            this.age = age//隐式调用父类构造子

          }

        });



        var pat = new Pat('pat',18);

        dom.console.log(pat.name)//pat

        dom.console.log(pat.age)//18

        pat.speak();//pat said bla bla bla

单例类。


        var God = dom.oop({

          init:function(name){

            this.name = name;

            this.alertName = function(){

              dom.console.log(this.name)

            }

          },

          singleton:true//注意这里,使用singleton属性

        });

        var god = new God("耶和华");

        god.alertName();      //alerts 耶和华

        var lucifer = new God("撒旦");

        lucifer.alertName();   //alerts 耶和华

        dom.console.log(god === lucifer )//alerts true

      

内部方法,只能用于类的内部与其子类。注意,是方法不是属性。


        var Person = dom.oop({

          init: function(name){

            this.name = name;

          },

          "protected secret": function(){//定义一个内部方法,要用"protected "作为前缀

            return 'I sometimes like girly drinks';

          }, 



          describe: function(){

            return "Hi, I'm #{name}. #{secret}. I kid, I kid.".instead({

              name: this.name,

              secret: this.secret()

            });

          }

        });



        var scott = new Person('司徒正美');

        try{

          scott.secret()

        }catch(e){

          dom.console.error(e);//Error: The method "secret" is protected!

        }

        dom.console.log(scott.describe());//Hi, I'm Scott. I sometimes like girly drinks. I kid, I kid.

      

更多见文档!

文档下载地址

下载回来后对着文件点右键-->属性-->解除锁定。

如果大家对上述方法有什么更好的实现,请不吝赐救!

人人都想有套房,为房辛苦为房忙,薪金贬值囊中涩,房价攀高节节扬;也曾誓做租房客,不助房商做盗强,多年女友离我去,没房谁做你新娘! 怨天怨地怨父母,生不逢时世态凉,人间广厦千万所,何处容我把身藏! 节衣缩食攒首付,借遍亲友与同窗,总算看到东方亮,却告房政有新章;政府调控只靠税,羊毛出处还是羊,未见房价有所减,倒为官家填满仓! 量力而行精打算,勉强买套小平方,窝大窝小终是有,手里有房心不慌。 新房到手喜一瞬,做上房奴苦漫长:工资月月无所剩,利率频调总受伤,戒烟戒酒减消费,加班加点为还偿;现任女友看房嫁,只能分享不分当,人过三十无生养,嫌贫不敢要儿郎;都说男人该潇洒,兜里无钱怎风光,人前总觉三分矮,背后更感九转肠! 哎,为房累,致心茫,苦难奈,欲崩狂, 曾经年少风华茂,而今华发早生霜,半世蹉跎半世过,一生幸福一生亡!

你可能感兴趣的:(framework)