重构- 关于可读性、原则和模式 中国网站技术部-市场开发部-前端(魏琪君) UED Team Design
主要内容 <ul><li>可读性 </li></ul><ul><li>原则和模式 </li></ul>
可读性-形 <ul><li>向下规则 </li></ul><ul><li>方法短小,缩进层次不超过 3 </li></ul>
缩进
摘录《代码整洁之道》 <ul><li>在 20 世纪 80 年代,常说函数不该长于一屏(那时候显示屏分辨率低,只有 24 行) </li></ul><ul><li>函数应该有多短小 ?  通常来说,应该短于代码清单 3-2 中的函数 ,  代码...
摘录《软件开发沉思录》 <ul><li>方法只使用一级缩进 </li></ul><ul><li>拒绝使用 else 关键字 </li></ul><ul><li>一句代码只有一个 '.' </li></ul><ul><li>不要使用缩写 </li...
可读性-意 <ul><li>统一词汇 </li></ul><ul><li>书写方式 </li></ul>
统一词汇 <ul><li>doc , header, content, footer </li></ul><ul><li>tag, alitalk, dialog, topbar </li></ul><ul><li>http://fd.aliu...
使用同样的词汇书写和交流
action <ul><li>希望我们有一个丰富的词汇库 </li></ul><ul><li>组件化从统一词汇做起 </li></ul>
如何去写代码 <ul><li>围绕我们用词汇建立的对象,用代码描述它和对它们的操作 </li></ul><ul><li>从整体到局部,从抽象到具体,建立不同层次 </li></ul><ul><li>让每一层次简单(认知超载) </li></ul>
一个例子:选择产品组件 <ul><li>http://fd.aliued.cn/doc/page/.personal/qijun.weiqj/design/offer-chooser.png </li></ul>
需求 1: OfferChooser 可以渲染在任意节点上
需求 2 :使用 OfferChooserDialog ,可以以对话框的形式使用
OfferChooser 由两部分组成
SourceOfferPart 主要由三部分组成 <ul><li>SearchPanel, OfferList, PagingNav </li></ul>
SearchPanel 由一个自定义的类目下拉框和普通的搜索功能组成
SelectedOfferPart
问题? <ul><li>每个类各司其职,做自己份内的事,因为自己的功能比较少,所以相对也会比较简单 </li></ul><ul><li>1.  类和类之间肯定有依赖,肯定有通信,那如何解决? </li></ul><ul><li>2.  开始仅知...
坏味道 1 :长且重复的方法名
提取,形成 SearchPanel
现在的 ChooserOffer
代码行数和类数量 <ul><li>平均方法代码行数: 25 行 </li></ul><ul><li>类中方法数量:保持 8 个以内 </li></ul><ul><li>原则:单一职责原则( SRP ) </li></ul>
原则和模式 <ul><li>刚才的未解决问题: </li></ul><ul><li>类和类之间肯定有依赖,肯定有通信,那如何解决? </li></ul>
类和类的关系 <ul><li>1.  继承 </li></ul><ul><li>2.  组合 </li></ul>
类图
继承-单例
继承-多例
组合
原则 <ul><li>优先使用组合,而不是继承 </li></ul><ul><li>( prefer composition over inheritance ) </li></ul><ul><li>继承带来很强的耦合性,特别是在强类型语言中 ...
根据 耦合性 对继承进行分类 <ul><li>子类仅依赖父类的公有方法 </li></ul>
根据 耦合性 对继承进行分类 <ul><li>子类依赖父类的非公有方法 ( 重写或调用父类的保护级方法 ) </li></ul>
更适合 JS 的原则 <ul><li>“ 优先使用组合,然后再是第 1 类继承 ,  慎重使用第 2 类继承” </li></ul><ul><li>应该记住的: </li></ul><ul><li>一个类能否被继承是一个设计问题,而不是捡到便宜...
稳定依赖原则( DIP ) <ul><li>解决依赖性 </li></ul><ul><li>实际上这个原则被称为 “依赖倒置原则”, 为了更好地理解,我弱化了这个原则 </li></ul><ul><li>“ 模块应该依赖于比它更稳定的模块” <...
[摘录]《敏捷软件开发,原则模式和实践》 <ul><li>a. 高层模块不应该依赖于低层模块。二者都应该依赖于抽象 </li></ul><ul><li>b. 抽象不应该依赖于细节。细节应该依赖于抽象。 </li></ul>
问题? <ul><li>那稳定的类要调用非稳定的类,或者模块和模块之间需要通信怎么办 ? </li></ul><ul><li>我们引入一个中间层(思考  $.ajax 的回调和 自定义事件) </li></ul>
实现
依赖注入( DI )
实际应用 <ul><li>OfferChooser ,点击 SourceOfferPart .select, SelectedOfferPart 需要做一些事 </li></ul>
引入间接层:使用自定义事件
题外话 <ul><li>有时候整个页面中的交互,我们可以使用触发在 window 上的自定义事件 </li></ul>
开放封闭原则( OCP ) <ul><li>解决扩展性 </li></ul><ul><li>“ Closed for Modification; Open for Extension” </li></ul><ul><li>对变更关闭,对扩展开放...
解析 OCP <ul><li>我们应该把模块写成:  </li></ul><ul><li>只要添加代码就能完成扩展, 而不需要修改原来的代码 </li></ul><ul><li>这个原则不是教我们怎么做, 而是教我们做成怎么样。 </li></ul>
一个例子
再一个例子
问题 <ul><li>难道我一开始就写成那样吗? OCP? </li></ul><ul><li>重构:受一次伤原则 </li></ul>
总结 <ul><li>方法组成代码“一级结构”。 </li></ul><ul><li>长度短,名称精炼,向下规则 </li></ul><ul><li>类以及类之间的关系,组成代码的“二级结构” </li></ul><ul><li>五大原则( D...
模式新视角
设计模式是一套词汇 <ul><li>我们对 Offer 进行一个排序,只要实现这个 Compare 接口就行了, 我们原来有这样的实现的,只是接口形式不一样,所以我们做个 Adapter 就好了 </li></ul><ul><li>我们在取数上...
重意不重形 <ul><li>看一个模式时,只要看它的“意图”,“遵循的原则”,还有“名称” </li></ul><ul><li>稍微看一下实现,看看能否用其他更优雅的实现,然后把类图和实现忘掉 </li></ul><ul><li>使用时,突然感...
最后一个例子 <ul><li>http://fd.aliued.cn/doc/page/.personal/qijun.weiqj/design </li></ul>
画出类图
策略( Strategy 或 Policy) <ul><li>原则? </li></ul><ul><li>开放封闭原则 OCP </li></ul><ul><li>依赖倒置原则 DIP </li></ul><ul><li>单一职责原则  SRP...
回顾 <ul><li>可读性 </li></ul><ul><ul><li>形: 方法小,向下规则 </li></ul></ul><ul><ul><li>意: 词汇, 分层描述 </li></ul></ul><ul><li>原则 </li></u...
Upcoming SlideShare
Loading in...5
×

魏琪君-重构-关于可读性、原则和模式

753

Published on

Published in: Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
753
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

魏琪君-重构-关于可读性、原则和模式

  1. 1. 重构- 关于可读性、原则和模式 中国网站技术部-市场开发部-前端(魏琪君) UED Team Design
  2. 2. 主要内容 <ul><li>可读性 </li></ul><ul><li>原则和模式 </li></ul>
  3. 3. 可读性-形 <ul><li>向下规则 </li></ul><ul><li>方法短小,缩进层次不超过 3 </li></ul>
  4. 4. 缩进
  5. 5. 摘录《代码整洁之道》 <ul><li>在 20 世纪 80 年代,常说函数不该长于一屏(那时候显示屏分辨率低,只有 24 行) </li></ul><ul><li>函数应该有多短小 ? 通常来说,应该短于代码清单 3-2 中的函数 , 代码清单 3-2 实在应该缩短成代码清单 3-3 这个样子 </li></ul><ul><li>我数了数清单 3-2 ,代码行数是 14 行, 而 3-3 是 6 行, 而且是包含最后的大括号的 </li></ul>
  6. 6. 摘录《软件开发沉思录》 <ul><li>方法只使用一级缩进 </li></ul><ul><li>拒绝使用 else 关键字 </li></ul><ul><li>一句代码只有一个 '.' </li></ul><ul><li>不要使用缩写 </li></ul>
  7. 7. 可读性-意 <ul><li>统一词汇 </li></ul><ul><li>书写方式 </li></ul>
  8. 8. 统一词汇 <ul><li>doc , header, content, footer </li></ul><ul><li>tag, alitalk, dialog, topbar </li></ul><ul><li>http://fd.aliued.cn/doc/page/.personal/qijun.weiqj/design/wp.png </li></ul><ul><li>http://fd.aliued.cn/doc/page/.personal/qijun.weiqj/design/offer-chooser.png </li></ul>
  9. 9. 使用同样的词汇书写和交流
  10. 10. action <ul><li>希望我们有一个丰富的词汇库 </li></ul><ul><li>组件化从统一词汇做起 </li></ul>
  11. 11. 如何去写代码 <ul><li>围绕我们用词汇建立的对象,用代码描述它和对它们的操作 </li></ul><ul><li>从整体到局部,从抽象到具体,建立不同层次 </li></ul><ul><li>让每一层次简单(认知超载) </li></ul>
  12. 12. 一个例子:选择产品组件 <ul><li>http://fd.aliued.cn/doc/page/.personal/qijun.weiqj/design/offer-chooser.png </li></ul>
  13. 13. 需求 1: OfferChooser 可以渲染在任意节点上
  14. 14. 需求 2 :使用 OfferChooserDialog ,可以以对话框的形式使用
  15. 15. OfferChooser 由两部分组成
  16. 16. SourceOfferPart 主要由三部分组成 <ul><li>SearchPanel, OfferList, PagingNav </li></ul>
  17. 17. SearchPanel 由一个自定义的类目下拉框和普通的搜索功能组成
  18. 18. SelectedOfferPart
  19. 19. 问题? <ul><li>每个类各司其职,做自己份内的事,因为自己的功能比较少,所以相对也会比较简单 </li></ul><ul><li>1. 类和类之间肯定有依赖,肯定有通信,那如何解决? </li></ul><ul><li>2. 开始仅知道必须要有 ChooserOffer 类和 ChooserOfferDialog 类, 因为这是由需求决定的。 那 SearchPanel, PagingNav 等类 我怎么想得到呢 ? 不能全部都写在一个类中吗? </li></ul>
  20. 20. 坏味道 1 :长且重复的方法名
  21. 21. 提取,形成 SearchPanel
  22. 22. 现在的 ChooserOffer
  23. 23. 代码行数和类数量 <ul><li>平均方法代码行数: 25 行 </li></ul><ul><li>类中方法数量:保持 8 个以内 </li></ul><ul><li>原则:单一职责原则( SRP ) </li></ul>
  24. 24. 原则和模式 <ul><li>刚才的未解决问题: </li></ul><ul><li>类和类之间肯定有依赖,肯定有通信,那如何解决? </li></ul>
  25. 25. 类和类的关系 <ul><li>1. 继承 </li></ul><ul><li>2. 组合 </li></ul>
  26. 26. 类图
  27. 27. 继承-单例
  28. 28. 继承-多例
  29. 29. 组合
  30. 30. 原则 <ul><li>优先使用组合,而不是继承 </li></ul><ul><li>( prefer composition over inheritance ) </li></ul><ul><li>继承带来很强的耦合性,特别是在强类型语言中 </li></ul><ul><li>在 JS 中,继承的耦合会低一些 </li></ul>
  31. 31. 根据 耦合性 对继承进行分类 <ul><li>子类仅依赖父类的公有方法 </li></ul>
  32. 32. 根据 耦合性 对继承进行分类 <ul><li>子类依赖父类的非公有方法 ( 重写或调用父类的保护级方法 ) </li></ul>
  33. 33. 更适合 JS 的原则 <ul><li>“ 优先使用组合,然后再是第 1 类继承 , 慎重使用第 2 类继承” </li></ul><ul><li>应该记住的: </li></ul><ul><li>一个类能否被继承是一个设计问题,而不是捡到便宜 </li></ul><ul><li>除此外: </li></ul><ul><li>继承是否合理是否必要,可以看原则: LSP (里氏替换原则) </li></ul>
  34. 34. 稳定依赖原则( DIP ) <ul><li>解决依赖性 </li></ul><ul><li>实际上这个原则被称为 “依赖倒置原则”, 为了更好地理解,我弱化了这个原则 </li></ul><ul><li>“ 模块应该依赖于比它更稳定的模块” </li></ul><ul><li>思考: </li></ul><ul><li>fdev4, core, widget, ui-core </li></ul><ul><li>global/module/page, 页面组件 </li></ul>
  35. 35. [摘录]《敏捷软件开发,原则模式和实践》 <ul><li>a. 高层模块不应该依赖于低层模块。二者都应该依赖于抽象 </li></ul><ul><li>b. 抽象不应该依赖于细节。细节应该依赖于抽象。 </li></ul>
  36. 36. 问题? <ul><li>那稳定的类要调用非稳定的类,或者模块和模块之间需要通信怎么办 ? </li></ul><ul><li>我们引入一个中间层(思考 $.ajax 的回调和 自定义事件) </li></ul>
  37. 37. 实现
  38. 38. 依赖注入( DI )
  39. 39. 实际应用 <ul><li>OfferChooser ,点击 SourceOfferPart .select, SelectedOfferPart 需要做一些事 </li></ul>
  40. 40. 引入间接层:使用自定义事件
  41. 41. 题外话 <ul><li>有时候整个页面中的交互,我们可以使用触发在 window 上的自定义事件 </li></ul>
  42. 42. 开放封闭原则( OCP ) <ul><li>解决扩展性 </li></ul><ul><li>“ Closed for Modification; Open for Extension” </li></ul><ul><li>对变更关闭,对扩展开放 </li></ul>
  43. 43. 解析 OCP <ul><li>我们应该把模块写成: </li></ul><ul><li>只要添加代码就能完成扩展, 而不需要修改原来的代码 </li></ul><ul><li>这个原则不是教我们怎么做, 而是教我们做成怎么样。 </li></ul>
  44. 44. 一个例子
  45. 45. 再一个例子
  46. 46. 问题 <ul><li>难道我一开始就写成那样吗? OCP? </li></ul><ul><li>重构:受一次伤原则 </li></ul>
  47. 47. 总结 <ul><li>方法组成代码“一级结构”。 </li></ul><ul><li>长度短,名称精炼,向下规则 </li></ul><ul><li>类以及类之间的关系,组成代码的“二级结构” </li></ul><ul><li>五大原则( DIP , OCP , LSP , SRP ),以及我们未接触的 ISP </li></ul><ul><li>优先使用组合等 </li></ul><ul><li>类和类形成包,包以及包之间的关系,组成代码的“三级结构” </li></ul><ul><li>遵循共同的原则: 简单 </li></ul>
  48. 48. 模式新视角
  49. 49. 设计模式是一套词汇 <ul><li>我们对 Offer 进行一个排序,只要实现这个 Compare 接口就行了, 我们原来有这样的实现的,只是接口形式不一样,所以我们做个 Adapter 就好了 </li></ul><ul><li>我们在取数上引入了 cache ,但我想让调用方透明,我们引入一个 Proxy... </li></ul><ul><li>我们还是要使用原来的那些方法的,但是太多了,我们做一个小小的 Facade, 这样我们就不用管原来那堆东西了 </li></ul><ul><li>矣~~,这个类构造太麻烦了,弄个 Factory 方便构造,同时把依赖注入, </li></ul><ul><li>还有还有, 这两个类的依赖不行,使用一个接口或者 Observer 反转一下依赖 </li></ul><ul><li>嗯,这一系列操作,我们把它弄成一个一个 Command 序列化掉 ... 存起来,下次恢复再执行 </li></ul><ul><li>这个验证框架扩展起来不是很方便,验证逻辑其实就是一个一个 Strategy 嘛, 改改~~ </li></ul>
  50. 50. 重意不重形 <ul><li>看一个模式时,只要看它的“意图”,“遵循的原则”,还有“名称” </li></ul><ul><li>稍微看一下实现,看看能否用其他更优雅的实现,然后把类图和实现忘掉 </li></ul><ul><li>使用时,突然感觉到自己正在使用某种模式, 这样就可以了。 </li></ul><ul><li>即不经意间使用模式 </li></ul><ul><li>重要的是知道什么时候不使用它 </li></ul>
  51. 51. 最后一个例子 <ul><li>http://fd.aliued.cn/doc/page/.personal/qijun.weiqj/design </li></ul>
  52. 52. 画出类图
  53. 53. 策略( Strategy 或 Policy) <ul><li>原则? </li></ul><ul><li>开放封闭原则 OCP </li></ul><ul><li>依赖倒置原则 DIP </li></ul><ul><li>单一职责原则 SRP (一个类只有一个引起它变化的原因) </li></ul><ul><li>优先使用组合,而不是继承 </li></ul><ul><li>prefer composition over inheritance </li></ul>
  54. 54. 回顾 <ul><li>可读性 </li></ul><ul><ul><li>形: 方法小,向下规则 </li></ul></ul><ul><ul><li>意: 词汇, 分层描述 </li></ul></ul><ul><li>原则 </li></ul><ul><ul><li>依赖倒置(稳定依赖)原则 DIP </li></ul></ul><ul><ul><li>开放封闭原则 OCP </li></ul></ul><ul><ul><li>优先使用组合 </li></ul></ul><ul><li>重构 </li></ul><ul><ul><li>提取方法形成类 </li></ul></ul><ul><ul><li>受一次伤原理 </li></ul></ul><ul><li>模式 </li></ul><ul><ul><li>设计模式是一套用于交流的词汇 </li></ul></ul><ul><ul><li>策略模式 (Strategy) </li></ul></ul>
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×