Design Pattern: Not Just Mixin Pattern
2015-07-15 15:35
477 查看
Brief
从Mix-In模式到Mixin模式,中文常用翻译为“混入/织入模式”。单纯从名字上看不到多少端倪,而通过采用Mixin模式的jQuery.extend我们是否可以认为Mixin模式就是深拷贝的代名词呢?
本文试图从继承机制入手对Mixin模式进行剖析,若有纰漏请大家指正,谢谢。
The Fact of Inheritance
首先让我们一起探讨一下继承机制吧。作为OOP的三个重要特性(Inheritance,Polymorphism,and Encapsulation)之一,继承应该是和Encapsulation关系最紧密。
试想一下,现在我们得到需求分析后要对问题做概念模型设计,过程大概就是从具象化->抽象化->再具象化,而在抽象化时自然而然需要提取具象的共同点得到简单直接的识别模型(如:广东人啥都吃,外国教育就是好),而再具象化时则需要构建更为明确的含义更丰富的认知模型(广东人有的吃猫肉,有的不吃),但它始终是识别模型的具象,也就始终依赖识别模型。
认知模型 多对多 识别模型,如 广东人有的会做生意,有的喜欢打工(广东人有的吃猫肉,有的不吃) 对 广东人会做生意(广东人啥都吃)
PS:认知模型、识别模型均为本人老作出来,识别模型就如文章title,略看后大概知道文章方向;认知模型如文章的content,细看才了解文章的含义。
The Diamond Problem from Multiple Inheritance
从上文了解到认知模型可对应多个识别模型,那么自然而然就需要多继承了,而C++和Python均支持这一语言特性。
示例:
View Code
Conclusion
后续我们将继续探讨C#和Java实现Mixin Pattern的方式,敬请期待,哈哈!
尊重原创,转载请注明来自:/article/4741163.html ^_^肥子John
Thanks
http://hax.iteye.com/blog/182339 http://cxyclub.cn/n/34324/ http://wiki.jikexueyuan.com/project/javascript-design-patterns/mixin.html http://www.zhihu.com/question/20778853 https://en.wikipedia.org/wiki/Mixin https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem http://codecrafter.blogspot.com/2011/03/c-mixins-with-state.html http://codecrafter.blogspot.com/2010/02/c-quasi-mixins-example.html http://stackoverflow.com/questions/6644668/mixins-with-c-sharp-4-0 http://www.sitepoint.com/ruby-mixins-2/ http://www.tutorialspoint.com/ruby/ruby_object_oriented.htm http://www.ibm.com/developerworks/cn/java/j-diag1203/ http://www.linuxjournal.com/node/4540/print
从Mix-In模式到Mixin模式,中文常用翻译为“混入/织入模式”。单纯从名字上看不到多少端倪,而通过采用Mixin模式的jQuery.extend我们是否可以认为Mixin模式就是深拷贝的代名词呢?
本文试图从继承机制入手对Mixin模式进行剖析,若有纰漏请大家指正,谢谢。
The Fact of Inheritance
首先让我们一起探讨一下继承机制吧。作为OOP的三个重要特性(Inheritance,Polymorphism,and Encapsulation)之一,继承应该是和Encapsulation关系最紧密。
试想一下,现在我们得到需求分析后要对问题做概念模型设计,过程大概就是从具象化->抽象化->再具象化,而在抽象化时自然而然需要提取具象的共同点得到简单直接的识别模型(如:广东人啥都吃,外国教育就是好),而再具象化时则需要构建更为明确的含义更丰富的认知模型(广东人有的吃猫肉,有的不吃),但它始终是识别模型的具象,也就始终依赖识别模型。
认知模型 多对多 识别模型,如 广东人有的会做生意,有的喜欢打工(广东人有的吃猫肉,有的不吃) 对 广东人会做生意(广东人啥都吃)
PS:认知模型、识别模型均为本人老作出来,识别模型就如文章title,略看后大概知道文章方向;认知模型如文章的content,细看才了解文章的含义。
The Diamond Problem from Multiple Inheritance
从上文了解到认知模型可对应多个识别模型,那么自然而然就需要多继承了,而C++和Python均支持这一语言特性。
示例:
/*! * defc * author: fsjohnhuang * version: 0.1.0 * blog: fsjohnhuang.cnblogs.com * description: define class with single inheritance, multiple mixins * sample: * defc('omg.JS', { * ctor: function(version){ * this.ver = verison * }, * author: 'Brendan Eich', * getAuthor: function(){ return this.author } * }) * var ES5 = defc('omg.ES5', 'omg.JS', { * ctor: function(version){} * }) * var mixins = [{isGreat: true, hasModule: function(){return true}}] * var ES6 = defc('omg.ES6', ES5, mixins, { * ctor: function(version){}, * getAuthor: function(){ * var author = zuper() // invoke method of super class which is the same signature * return [author, 'JSers'] * } * }) * var es6 = new ES6('2015') * var es6_copy = new ES6('2015') * assert.deepEquals(['Branden Eich', 'JSers'], es6.getAuthor()) * assert.equals(true, es6.isGreat) * ES6._mixin({isGreat: false}) * assert.equals(false, es6_copy.isGreat) * * defc.mixin(es6, {isGreat: true}) * assert.equals(true, es6.isGreat) * assert.equals(false, es6_copy.isGreat) */ ;(function(factory){ var require = function(module){ return require[module] } require.utils = { isArray: function(obj){ return /Array/.test(Object.prototype.toString.call(obj)) }, isFn: function(obj){ return typeof obj === 'function' }, isObj: function(obj){ return /Object/.test(Object.prototype.toString.call(obj)) }, isStr: function(obj){ return '' + obj === obj }, noop: function(){} } factory(require, this) }(function(require, exports){ var VERSION = '0.1.0' var utils = require('utils') var clazzes = {} /** * @method defc * @public * @param {DOMString} clzName - the full qualified name of class, i.e. com.fsjohnhuang.Post * @param {Function|DOMString|Array.<Object>|Object} [zuper|mixins|members] - super class, mixin classes array or members of class * @param {Array.<Object>|Object} [mixins|members] - mixin classes array or members of class * @param {Object} [members] - members of class. ps: property "ctor" is the contructor of class * @returns {Object} */ var defc = exports.defc = function(clzName, zuper, mixins, members){ if (clazzes[clzName]) return clazzes[clzName].ctor var args = arguments, argCount = args.length members = utils.isObj(args[argCount-1]) && args[argCount-1] || {} mixins = utils.isArray(mixins) && mixins || utils.isArray(zuper) && zuper || [] zuper = utils.isFn(zuper) && zuper || utils.isStr(zuper) && clazzes[zuper] && clazzes[zuper].ctor || 0 var clz = clazzes[clzName] = {} var ctor = clz.ctor = function(){ // execute constructor of super class if (zuper) zuper.apply(this, arguments) // execute constructor members.ctor && members.ctor.apply(this, arguments) // contruct public fields for(var m in members) if(utils.isFn(this[m] = members[m])) delete this[m] } ctor.toString = function(){ return (members.ctor || utils.noop).toString() } // extends super class if (zuper){ var M = function(){} M.prototype = zuper.prototype ctor.prototype = new M() ctor.prototype.contructor = members.ctor || utils.noop } // construct public methods for(var m in members) if(m === 'ctor' || !utils.isFn(members[m])) continue else if(!(zuper.prototype || zuper.constructor.prototype)[m]) ctor.prototype[m] = members[m] else (function(m){ // operate the memebers of child within the methods of super class var _super = function(self){ return function(){ return (zuper.prototype || zuper.constructor.prototype)[m].apply(self, arguments)} } var fnStr = members[m].toString() , idx = fnStr.indexOf('{') + 1 , nFnStr = fnStr.substring(0, idx) + ';var zuper = _super(this);' + fnStr.substring(idx) eval('ctor.prototype[m] = ' + nFnStr) }(m)) // do shallow mixins for(var mixin in mixins) for(var m in mixins[mixin]) ctor.prototype[m] = mixins[mixin][m] // additional methods ctor._mixin = function(/*...mixins*/){ var mixins = arguments for(var mixin in mixins) for(var m in mixins[mixin]) this.prototype[m] = mixins[mixin][m] } return ctor } /** * @method defc.mixin * @public * @param {Any} obj - mixin target * @param {...Object} mixins - mixin source */ defc.mixin = function(obj/*, ...mixins*/){ var mixins = Array.prototype.slice.call(arguments, 1) for(var mixin in mixins) for(var m in mixins[mixin]) obj[m] = mixins[mixin][m] } }))
View Code
Conclusion
后续我们将继续探讨C#和Java实现Mixin Pattern的方式,敬请期待,哈哈!
尊重原创,转载请注明来自:/article/4741163.html ^_^肥子John
Thanks
http://hax.iteye.com/blog/182339 http://cxyclub.cn/n/34324/ http://wiki.jikexueyuan.com/project/javascript-design-patterns/mixin.html http://www.zhihu.com/question/20778853 https://en.wikipedia.org/wiki/Mixin https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem http://codecrafter.blogspot.com/2011/03/c-mixins-with-state.html http://codecrafter.blogspot.com/2010/02/c-quasi-mixins-example.html http://stackoverflow.com/questions/6644668/mixins-with-c-sharp-4-0 http://www.sitepoint.com/ruby-mixins-2/ http://www.tutorialspoint.com/ruby/ruby_object_oriented.htm http://www.ibm.com/developerworks/cn/java/j-diag1203/ http://www.linuxjournal.com/node/4540/print
相关文章推荐
- NSMutableAttributedString 富文本删除线的用法
- SQL表复制
- poj解题报告——1037
- [转载] 尺度不变特征变换匹配算法详解
- android-percent-support-lib-sample
- AOP Spring
- Android利用ContentResolver查询的三种方式
- 定位问题:*** glibc detected *** : double free or corruption (!prev): 0x09b077d8
- Springmvc JSON交互
- 编译和链接的区别联系
- 【转】Java并发编程:Thread类的使用
- C#中调用MySQL存储过程的方法
- SQLServer 2008中用T-SQL创建邮件
- Android 开源框架Universal-Image-Loader完全解析(三)---源代码解读
- [C++设计模式] decorator 装饰者模式
- JQuery一些基础点区分
- Java项目经验
- 解决STM32 SPI 半残废 NSS无法拉高
- C/C++中Sqlite使用简介
- `java.lang.ClassNotFoundException: org.springframework.web.util.Log4jConfigListener`