- "use strict";
- /**
- 面向对象思想的辅助实现模块;
-
- Feartures :
- 1. klass :类继承;实现执行指针,类常用方法,继承路径
- 2. factory :对象/类工厂方法;
-
- Update Note:
- + 2014.6 :Created
-
- @module OOP
- */
- _stDefine('oop', function(st) {
- //初始化扩展函数
- var _onKlassInit = st.promiseEvent(),
- /**
- * klass的基类对象
- * @class klassBase
- */
- _klassBase = {
- /**
- 调用原型链方法
- @method callProto
- @param name {string} 需要执行的原型链方法名
- @param [args] {array} 执行参数
- @return [object] 返回执行结果
- @demo test/base/oop.js [klassBase - callProto] {执行原型链方法}
- */
- callProto : function(name,args){
- var fn = this._$fn[name];
- if(fn)
- return fn.apply(this,args);
- },
- /**
- 获取基类对象
- @method getBase
- @param [baseName] {string} 基类名称,不设置则返回父类
- @return [object] 返回基类
- @demo test/base/oop.js [klassBase - getBase] {获取基类对象}
- */
- getBase: function(baseName) {
- var self = this,
- parent = self._$super;
-
- if (baseName && typeof baseName == 'number')
- baseName = self._$inheirts[baseName];
-
- if (parent) {
- if (baseName) {
- while (parent && parent._$kName != baseName) {
- parent = parent._$super;
- }
- } else if (parent._$kName == self._$kName) {
- return null;
- }
- }
- return parent;
- },
- /**
- 调用基类的方法
- @method callBase
- @param {string} fnName 方法名称
- @param {string} [baseName] 基类名称
- @param {array} [args] 方法参数数组
- @return {object} 执行结果
- @demo test/base/oop.js [klassBase - callBase] {调用父类}
- @demo test/base/oop.js [muilt heirht - callBase] {多级继承示例}
- */
- callBase: function(fnName, baseName, args) {
- var self = this,
- base = self._$super,
- fn, result, current, indicator = self._$indicator;
-
- if (!base)
- return;
-
- if (arguments.length < 3) {
- args = baseName;
- baseName = null;
- }
-
- if (baseName)
- base = self.getBase(baseName);
- else if (current = indicator[fnName])
- base = current._$super || current.fn._$super || current;
-
- if (base && (fn = base[fnName])) {
- indicator[fnName] = base;
- result = fn.apply(this, args);
- indicator[fnName] = null;
- }
- return result;
- },
- /**
- 类扩展方法
- @method extend
- @param {object} prop 扩展的属性和方法对象
- @chainable
- @demo test/base/oop.js [klassBase - extend] {类扩展}
- */
- extend: function(prop) {
- st.mergeObj(this, prop);
- return this;
- }
- };
-
- st.conf('oop-KlassBase',_klassBase);
-
- /**
- js类创建,具有执行指针功能(解决了多级继承域对象的问题)
-
- 此外提供两种全局扩展方式:
- 1. 基于原形链的基类扩展,使用st.conf('oop-KlassBase'),可以取到基类对象进行扩展
- 2. 在类初始化时,对实例化的对象进行扩展,可以使用st.onKlassInit对象进行添加扩展方法。st.onKlassInit 是promiseEvent对象,st.onKlassInit(obj,config);
-
- @class klass
- @constructor
- @extend klassBase
- @param {string} name 类名称
- @param {object} prop 类的属性和方法
- @param {klass|object|function} [parent] 父类
- @param {object} [config] 扩展参数
- @return {klass} 返回类
- @demo test/base/oop.js [class init] {实例化}
- @demo test/base/oop.js [inheirt] {类继承}
- @demo test/base/oop.js [klass prop check] {继承特性检查}
- @demo test/base/oop.js [muilt heirht - callBase] {多级继承}
- */
- function klass(name, prop, parent, config) {
- var _super, _proto, _prop = prop,
- _inheirts = [name],
- _obj = function() {
- var self = this,
- args = arguments,
- len = args.length;
-
- //自执行初始化判断
- if (!(self instanceof _obj)) {
- if (len === 0)
- return new _obj();
- if (len < 4)
- return new _obj(args[0], args[1], args[2]);
- else if (len < 7)
- return new _obj(args[0], args[1], args[2], args[3], args[4], args[5]);
- else
- return new _obj(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
- }
- //设置指针对象
- self._$indicator = {};
- //设置原型链
- self._$fn = _proto;
- //执行扩展方法
- _onKlassInit.fireWith(self,config);
- //klassInit默认初始化
- self.klassInit && self.klassInit.apply(self, args);
- }
-
- if (parent) {
- _super = parent.prototype || parent;
- _proto = _obj.prototype = Object.create(_super);
- _proto._$super = _super;
- _proto.constructor = parent;
- //添加父的继承路径
- if (_super._$inheirts)
- _inheirts = _inheirts.concat(_super._$inheirts);
- else
- _inheirts.push(parent.name);
- } else
- _proto = st.mergeObj(_obj.prototype, _klassBase);
-
- _obj.fn = _proto;
-
- st.mergeMulti([_proto, _prop,{
- //类标示
- _$klass: true,
- //类名
- _$kName: name,
- //继承链
- _$inheirts: _inheirts
- }]);
-
- return _obj;
- }
-
- // _onKlassInit.add('attachTrigger', function(config) {
- // var trigger = config.trigger;
- // trigger && st.attachTrigger(this, trigger.iFace, trigger.mode);
- // })
-
- /**
- * factory并不只是指的是工厂模式。在factory要求定义一个基础对象,这个对象可以是基类,也可以是模板对象或者是接口。然后factory就已此基础对象为基础,其他添加或者创建的对象,继承或者是复制基础对象的属性和方法。factory在提供一系列方法来对这些对象做控制。
- factory经过简单的处理可以实现工厂、外观、模板等设计模式。
- * @class factory
- * @constructor
- * @extends klass
- * @param {string} name 工厂名称
- * @param {object} base 基类对象,所有在工厂中添加的对象都以base为基础
- * @param {object} [proto] 工厂的扩展属性和方法对象
- * @param {string} [type] 工厂的类型;
- * 1. 默认:类实例化后的对象;
- * 2. class:类对象,未实例化;
- * 3. merge:对象复制合并
- * @param {boolean} [initDefault] 是否将base设置成为默认的对象;当使用factory.get找不到对象时返回默认对象
- * @return {factory} 返回创建的工厂对象
- * @demo test/base/oop.js [factory inheirt] {继承}
- * @demo test/base/oop.js [factory class mode] {类继承模式}
- * @demo test/base/oop.js [factory merge mode] {对象合并模式}
- */
- function factory(name, base, proto, type, initDefault) {
- var _store = {}, _base = base,
- _proto, _type, _initDefault,
- args = arguments,
- argsLen = args.length,
- argType,arg, i = 2,
- mergeMode, klassMode, needInit, _defaultItem;
-
-
- if(argsLen === 1 && typeof name === 'object'){
- _base = name.base;
- _proto = name.proto;
- _type = name.type;
- _initDefault = name.initDefault;
- name = name.name;
- }
- else if (argsLen > i) {
- for (; i < argsLen; i++) {
- if (arg = args[i]) {
- argType = typeof arg;
- if (argType === 'object')
- _proto = arg;
- else if (argType === 'string')
- _type = arg;
- else if (argType === 'boolean')
- _initDefault = arg;
- }
- }
- }
-
- if (_type === 'merge')
- mergeMode = true;
- else if (_type === 'class')
- klassMode = true;
- else
- needInit = true;
-
- mergeMode || (_base = klass(name + '_base',_base));
-
- //设置默认项
- _initDefault && (_defaultItem = needInit ? new _base : _base);
-
- /**
- 使用工厂创建产品方法,但不注册到factory中
- @method build
- @param {string} name 产品名称
- @param {object} item 产品特性
- @param {string} [parent] 父类名称,注册到factory中产品名称
- @return {object|klass} 返回创建的产品
- @demo test/base/oop.js [factory build]
- */
- function build(name, item, parent) {
- parent = parent ? find(parent) || _base : _base;
-
- item._$fType = name;
-
- if (mergeMode)
- return st.mix(true, item, parent);
- else {
- item = klass(name, item, parent);
- return klassMode ? item : new item;
- }
- }
-
- /**
- 添加产品方法,注册到factory中
- @method add
- @param {string} name 产品名称
- @param {object} item 产品特性
- @param {string} [parent] 父类名称,注册到factory中产品名称
- @return {object|klass} 返回创建的产品
- @demo test/base/oop.js [factory add]
- */
- function add(name, item, parent) {
- return (_store[name] = build(name, item, parent));
- }
-
- /**
- 查找注册的产品
- @method find
- @param {string} name 产品名称
- @param {object} defaultMode 是否在找不到产品的时候返回默认产品
- @return {object} 返回查找的产品
- */
- function find(name, defaultMode) {
- var obj;
- if (arguments.length === 0)
- return _defaultItem;
-
- if (name && (obj = _store[name])) {
- return obj;
- }
- return defaultMode ? _defaultItem : undefined;
- }
-
- /**
- 将注册的产品设置成默认产品
- @method setDefault
- @param {string} name 产品名称
- @chainable
- @demo test/base/oop.js [setDefault]
- */
- function setDefault(name) {
- _defaultItem = find(name, true);
- return this;
- }
-
- /**
- 在工厂中移除注册的产品
- @method remove
- @param {string} name 产品名称
- @chainable
- */
- function remove(name) {
- delete _store[name];
- }
-
- proto = st.mergeObj({
- build: build,
- add: add,
- find: find,
- remove: remove,
- setDefault: setDefault,
- /**
- 执行工厂中产品的方法,不会返回结果;当工厂类型为class时,则执行的则是原型链上的方法
- @method fire
- @param {string} name 方法名称
- @param {array} [args] 执行参数
- @param {function} [handler] 处理方法
- @demo test/base/oop.js [fire]
- */
- fire : function(name,args,handler){
- var fn,result,self = this;
- st.each(_store,function(n,item){
- if(item){
- item.fn && (item = item.fn);
- if(fn = item[name])
- {
- result = fn.apply(item,args);
- handler && handler.call(self,item,result);
- }
- }
- })
- }
- }, _proto);
-
- return klass(name, proto, null, {
- trigger: true
- })();
- }
-
- return {
- klass: klass,
- onKlassInit : _onKlassInit,
- factory: factory
- };
- })
-