SlideShare a Scribd company logo
组件交互模式的 非主流研究 ——  QWrap 2.0  前瞻:亚模块组件的设计
概要 我是概要,不是提纲  =.= 为什么要说这个? 模块之间的交互 直接调用的简单模式 传统的事件模型 —— 电话模式 组合和建立联系 ——  IM 模式 发出全局信息 —— 广播模式 更有效传播信息 —— 微博模式 还有没有别的方法? 接下来要做什么? 观察者模式的变体
为什么要说这个? 模块之间交互存在的问题 独立的模块之间有时候难于交互 业务需求的零散与模块独立完整之间的差异 业务需求变化意味着组件产品的功能增加 但是组件产品功能不断增加会导致问题 臃肿与适应性之间的平衡 组件随着不断升级功能越来越完善,但是。。。 完善也意味着更复杂了,从一定程度上更难使用了。。。 “ 亚模块组件”的设计 比模块更细粒度的代码复用
模块之间的交互 数据交互 A 模块给 B 模块提供数据 控制流程 A 模块状态改变引起 B 模块变化 多模块之间复杂交互(数据 + 控制) 多个模块的组合和互相影响(例如:相册)
最简单的直接调用 模块 B 调用模块 A 的方法 B.someMethod.call(this, A); 模块有可能调用一系列其他模块的方法 function(){ A.some.call… B.some.call… C.some.call… …… } 优点? 缺点?
事件模型 事件模型可能会写出这样的代码 void function () { // 加一个 proxy 属性 var d = new BB.SimpleDrag( { target : BB.Dom.query("td"), withProxy : true } , [ { source : BB.$('drag1'), proxy : BB.$('drag1-proxy') } , { source : BB.$('drag2') } ] ); d.ondragenter = function (e) { BB.Dom.setStyle(e.context.target, 'background-color', '#F00'); }; d.ondragover = function (e) { if (e.context.previousTarget && e.context.previousTarget != e.context.target) { BB.Dom.setStyle(e.context.previousTarget, 'background-color', 'transparent'); } e.context.previousTarget = e.context.target; BB.Dom.setStyle(e.context.target, 'background-color', '#F00'); }; d.ondragleave = function (e) { BB.Dom.setStyle(e.context.target, 'background-color', 'transparent'); }; d.ondragdrop = function (e) { alert('dragdrop'); }; d.oninvaliddrop = function (e) { alert('invaliddrop'); }; }();
事件模型 d.ondragenter  = function (e) { BB.Dom.setStyle(e.context.target, 'background-color', '#F00'); }; d.ondragover   = function (e) { if (e.context.previousTarget && e.context.previousTarget != e.context.target) { BB.Dom.setStyle(e.context.previousTarget, 'background-color', 'transparent'); } e.context.previousTarget = e.context.target; BB.Dom.setStyle(e.context.target, 'background-color', '#F00'); }; d.ondragleave  = function (e) { BB.Dom.setStyle(e.context.target, 'background-color', 'transparent'); };
事件模型 事件模型要求我们: 记住组件有哪些事件 一般在一个 handler 内要求完成所有的业务操作 需求变了往往意味着修改 handler 对应的执行代码 有时候用多投,但是多投有时候也很麻烦 每个组件都有一堆 onXxx 如果 pm 跟我们提需求, onXxx 可能会越来越多 交叉事件响应异常麻烦 例如 A 的 click 触发 B 的 focus , B 的 focus 又触发 C 和 D 的 update……
事件模型 组件之间的交互多了,事件模型会有很大的问题 组件耦合是一件痛苦的事情 click -> focus -> update drop -> selected -> highlight ……  那我们一般怎么做的? 组件尽量功能独立 一般很少考虑组件间的复杂交互 配置式的封装使用(如 panel 封装成 dialog ) 和 pm 砍需求,不给做
事件模型 有问题还是没问题? 逃避原理 一件事情我不想发生,我可以让它不发生 于是我说,没有这个问题 一个需求满足不了,我可以让这个需求不产生 于是我说,没有这个需求
事件模型 事实的真相 也许我们从来很少怀疑的设计出了问题 也许我们可以做得更好 让我们看看有什么别的方法可以做
广播模式 我改变了,不用亲自去处理,我可以说出来 a.broadcast({target:a.id,text:”I’ve been changed”}); b.receive( function(message){ if(message.target == someid){ b.doSomeChange(); b.broadcast({target:b, text:”I’ve been changed,too”,reason:a}); } } );
广播模式 好处? 模块 A 不需要知道模块 B 的存在 模块 A 只需要广播它状态的变化 模块 B 只知有消息存在,不关心 A 模块 A 和 B 的耦合度很低了 坏处? 广播意味着所有组件都能收到,不太好吧? 如何保证实现效率? 可能 receive 里有很多很多分支
新的模式 怎么做更好? 思考一下
新的模式 也许我们只需要改变一点点: // 类似 twitter 的观察者模式,可以看作是事件强化版,感觉比广播好,也更灵活 function Twitter(){ this.followers = []; } Twitter.prototype. tweet  = function(msg){ for(var i = 0; i < this.followers.length; i++){ var follower = this.followers[i]; if(follower.handler){ follower.handler.call(follower.target, msg); //deal } } } Twitter.prototype. follow  = function(master, handler){ master.followers.push({target:this, handler:handler}); }
新的模式 简单试试看: // 用 tabView 做一个简单的实验,但是这个不是组件,这个是散的 var tab = new Twitter(); var view = new Twitter(); view.follow (tab, function(msg){ var view = document.getElementById(&quot;view&quot;).getElementsByTagName(&quot;span&quot;); for(var i = 0; i < view.length; i++){ if(i == msg){ view[i].className = &quot;active&quot;; }else{ view[i].className = &quot;&quot;; } } }); var tabContainer = document.getElementById(&quot;tab&quot;); tabContainer.onclick = function(event){ var evt = event || window.event; var target = evt.srcElement || evt.target; if(target != this){ tab.tweet (target.innerHTML-1); } }
新的模式 和事件模型有什么区别? 单点发布 自愿收听 单向联接 分散传播
新的模式 还有哪些事情可以做 利用模式匹配解决分支很多的问题 b.follow(a,{ “ mouseover a”:function(message) { … }, “ click a”:function(message) { … } … });
新的模式 var matcher = FunctionH.overload. curry ( [function(){},,function(args){ return args.type+” a”; }] ); Twitter.prototype.tweet = function(msg){ for(var i = 0; i < this.followers.length; i++){ var follower = this.followers[i]; if(follower.handler){ matcher(follower.handler).call(follower.target,msg); } } }
新的模式 还有哪些事情可以做 信息的传播—— retweet b.follow(a, function(msg){ this.tweet(ObjectH.mix(addition,msg)); //retweet }); 信息的非实时处理 改改看? 其他好玩的事情? 就像我们在 twitter 上玩的那些花样
还有没有别的方法? 大家讨论
Q & A 谢谢!

More Related Content

PPTX
小谈Javascript设计模式
PPTX
函式 Functions
DOC
Free Marker中文文档
PPT
Ο επιτάφιος θρήνος
PPTX
το σεντούκι με τις πέντε κλειδαριές!
PPT
Evaluation question 6
 
PPT
Or slides final
DOC
πολυγυροσ
小谈Javascript设计模式
函式 Functions
Free Marker中文文档
Ο επιτάφιος θρήνος
το σεντούκι με τις πέντε κλειδαριές!
Evaluation question 6
 
Or slides final
πολυγυροσ

Viewers also liked (20)

PPTX
How to create the right startup ecosystem?
PDF
Surfaris
PDF
Brand and Leverage
PPT
Jills slides
PPT
Il slides final
PPS
Hong Kong To Beijing
PPT
Ross Owen - Minnesota’s Health Care Home Initiative in Context
PPT
WPO工具概览
KEY
PPT
Streamlining Eligibility and Enrollment Mendoza VA
PDF
Aprenda a instalar camaras de seguridad
PDF
Perl and Email #2/Kansai.pm第14回ミーティング@京都
PPS
Solar Impulse
PPTX
Qltg thv
PDF
إدراك الفساد المالي والإداري في العراق
PPT
Evaluation Question 6
 
PPTX
δραμα
PDF
ELS CONSELLS DE LA TORTUGA
DOCX
One Large - Bartender Tips From Cocktail About
PPTX
ο άγιος γεώργιος σκοτώνει το δράκο
How to create the right startup ecosystem?
Surfaris
Brand and Leverage
Jills slides
Il slides final
Hong Kong To Beijing
Ross Owen - Minnesota’s Health Care Home Initiative in Context
WPO工具概览
Streamlining Eligibility and Enrollment Mendoza VA
Aprenda a instalar camaras de seguridad
Perl and Email #2/Kansai.pm第14回ミーティング@京都
Solar Impulse
Qltg thv
إدراك الفساد المالي والإداري في العراق
Evaluation Question 6
 
δραμα
ELS CONSELLS DE LA TORTUGA
One Large - Bartender Tips From Cocktail About
ο άγιος γεώργιος σκοτώνει το δράκο
Ad

Similar to 组件交互模式的非主流研究 (20)

PDF
旺铺前端设计和实现
PDF
Spring 2.x 中文
PPTX
前端MVC之backbone
PDF
由一个简单的程序谈起――之二
DOC
用Jquery实现拖拽层
PDF
Struts+Spring+Hibernate整合教程
PDF
Struts+Spring+Hibernate整合教程
PDF
Backbone.js and MVW 101
PDF
Django development
PPT
Web base 吴志华
PPT
jQuery介绍@disandu.com
PPTX
前端测试
PPTX
前端测试
PPT
JavaScript 脚本控件(二)
PDF
JCConf 2024 - Java 22 & 23 新功能介紹
PDF
由一个简单的程序谈起--之四
DOC
Spring入门纲要
ODP
JavaScript Advanced Skill
PPT
Sql语句的优化
PDF
不断归零的前端人生 - 2016 中国软件开发者大会
旺铺前端设计和实现
Spring 2.x 中文
前端MVC之backbone
由一个简单的程序谈起――之二
用Jquery实现拖拽层
Struts+Spring+Hibernate整合教程
Struts+Spring+Hibernate整合教程
Backbone.js and MVW 101
Django development
Web base 吴志华
jQuery介绍@disandu.com
前端测试
前端测试
JavaScript 脚本控件(二)
JCConf 2024 - Java 22 & 23 新功能介紹
由一个简单的程序谈起--之四
Spring入门纲要
JavaScript Advanced Skill
Sql语句的优化
不断归零的前端人生 - 2016 中国软件开发者大会
Ad

组件交互模式的非主流研究

  • 1. 组件交互模式的 非主流研究 —— QWrap 2.0 前瞻:亚模块组件的设计
  • 2. 概要 我是概要,不是提纲 =.= 为什么要说这个? 模块之间的交互 直接调用的简单模式 传统的事件模型 —— 电话模式 组合和建立联系 —— IM 模式 发出全局信息 —— 广播模式 更有效传播信息 —— 微博模式 还有没有别的方法? 接下来要做什么? 观察者模式的变体
  • 3. 为什么要说这个? 模块之间交互存在的问题 独立的模块之间有时候难于交互 业务需求的零散与模块独立完整之间的差异 业务需求变化意味着组件产品的功能增加 但是组件产品功能不断增加会导致问题 臃肿与适应性之间的平衡 组件随着不断升级功能越来越完善,但是。。。 完善也意味着更复杂了,从一定程度上更难使用了。。。 “ 亚模块组件”的设计 比模块更细粒度的代码复用
  • 4. 模块之间的交互 数据交互 A 模块给 B 模块提供数据 控制流程 A 模块状态改变引起 B 模块变化 多模块之间复杂交互(数据 + 控制) 多个模块的组合和互相影响(例如:相册)
  • 5. 最简单的直接调用 模块 B 调用模块 A 的方法 B.someMethod.call(this, A); 模块有可能调用一系列其他模块的方法 function(){ A.some.call… B.some.call… C.some.call… …… } 优点? 缺点?
  • 6. 事件模型 事件模型可能会写出这样的代码 void function () { // 加一个 proxy 属性 var d = new BB.SimpleDrag( { target : BB.Dom.query(&quot;td&quot;), withProxy : true } , [ { source : BB.$('drag1'), proxy : BB.$('drag1-proxy') } , { source : BB.$('drag2') } ] ); d.ondragenter = function (e) { BB.Dom.setStyle(e.context.target, 'background-color', '#F00'); }; d.ondragover = function (e) { if (e.context.previousTarget && e.context.previousTarget != e.context.target) { BB.Dom.setStyle(e.context.previousTarget, 'background-color', 'transparent'); } e.context.previousTarget = e.context.target; BB.Dom.setStyle(e.context.target, 'background-color', '#F00'); }; d.ondragleave = function (e) { BB.Dom.setStyle(e.context.target, 'background-color', 'transparent'); }; d.ondragdrop = function (e) { alert('dragdrop'); }; d.oninvaliddrop = function (e) { alert('invaliddrop'); }; }();
  • 7. 事件模型 d.ondragenter = function (e) { BB.Dom.setStyle(e.context.target, 'background-color', '#F00'); }; d.ondragover = function (e) { if (e.context.previousTarget && e.context.previousTarget != e.context.target) { BB.Dom.setStyle(e.context.previousTarget, 'background-color', 'transparent'); } e.context.previousTarget = e.context.target; BB.Dom.setStyle(e.context.target, 'background-color', '#F00'); }; d.ondragleave = function (e) { BB.Dom.setStyle(e.context.target, 'background-color', 'transparent'); };
  • 8. 事件模型 事件模型要求我们: 记住组件有哪些事件 一般在一个 handler 内要求完成所有的业务操作 需求变了往往意味着修改 handler 对应的执行代码 有时候用多投,但是多投有时候也很麻烦 每个组件都有一堆 onXxx 如果 pm 跟我们提需求, onXxx 可能会越来越多 交叉事件响应异常麻烦 例如 A 的 click 触发 B 的 focus , B 的 focus 又触发 C 和 D 的 update……
  • 9. 事件模型 组件之间的交互多了,事件模型会有很大的问题 组件耦合是一件痛苦的事情 click -> focus -> update drop -> selected -> highlight …… 那我们一般怎么做的? 组件尽量功能独立 一般很少考虑组件间的复杂交互 配置式的封装使用(如 panel 封装成 dialog ) 和 pm 砍需求,不给做
  • 10. 事件模型 有问题还是没问题? 逃避原理 一件事情我不想发生,我可以让它不发生 于是我说,没有这个问题 一个需求满足不了,我可以让这个需求不产生 于是我说,没有这个需求
  • 11. 事件模型 事实的真相 也许我们从来很少怀疑的设计出了问题 也许我们可以做得更好 让我们看看有什么别的方法可以做
  • 12. 广播模式 我改变了,不用亲自去处理,我可以说出来 a.broadcast({target:a.id,text:”I’ve been changed”}); b.receive( function(message){ if(message.target == someid){ b.doSomeChange(); b.broadcast({target:b, text:”I’ve been changed,too”,reason:a}); } } );
  • 13. 广播模式 好处? 模块 A 不需要知道模块 B 的存在 模块 A 只需要广播它状态的变化 模块 B 只知有消息存在,不关心 A 模块 A 和 B 的耦合度很低了 坏处? 广播意味着所有组件都能收到,不太好吧? 如何保证实现效率? 可能 receive 里有很多很多分支
  • 15. 新的模式 也许我们只需要改变一点点: // 类似 twitter 的观察者模式,可以看作是事件强化版,感觉比广播好,也更灵活 function Twitter(){ this.followers = []; } Twitter.prototype. tweet = function(msg){ for(var i = 0; i < this.followers.length; i++){ var follower = this.followers[i]; if(follower.handler){ follower.handler.call(follower.target, msg); //deal } } } Twitter.prototype. follow = function(master, handler){ master.followers.push({target:this, handler:handler}); }
  • 16. 新的模式 简单试试看: // 用 tabView 做一个简单的实验,但是这个不是组件,这个是散的 var tab = new Twitter(); var view = new Twitter(); view.follow (tab, function(msg){ var view = document.getElementById(&quot;view&quot;).getElementsByTagName(&quot;span&quot;); for(var i = 0; i < view.length; i++){ if(i == msg){ view[i].className = &quot;active&quot;; }else{ view[i].className = &quot;&quot;; } } }); var tabContainer = document.getElementById(&quot;tab&quot;); tabContainer.onclick = function(event){ var evt = event || window.event; var target = evt.srcElement || evt.target; if(target != this){ tab.tweet (target.innerHTML-1); } }
  • 17. 新的模式 和事件模型有什么区别? 单点发布 自愿收听 单向联接 分散传播
  • 18. 新的模式 还有哪些事情可以做 利用模式匹配解决分支很多的问题 b.follow(a,{ “ mouseover a”:function(message) { … }, “ click a”:function(message) { … } … });
  • 19. 新的模式 var matcher = FunctionH.overload. curry ( [function(){},,function(args){ return args.type+” a”; }] ); Twitter.prototype.tweet = function(msg){ for(var i = 0; i < this.followers.length; i++){ var follower = this.followers[i]; if(follower.handler){ matcher(follower.handler).call(follower.target,msg); } } }
  • 20. 新的模式 还有哪些事情可以做 信息的传播—— retweet b.follow(a, function(msg){ this.tweet(ObjectH.mix(addition,msg)); //retweet }); 信息的非实时处理 改改看? 其他好玩的事情? 就像我们在 twitter 上玩的那些花样
  • 22. Q & A 谢谢!