SlideShare a Scribd company logo
1 of 58
重构-关于可读性、原则和模式
中国网站技术部-市场开发部-前端(魏琪君)




                        UED Team Design
主要内容
• 可读性
• 原则和模式
可读性-形
• 向下规则
• 方法短小 ( 不超过一屏 ) ,缩进层次不超过 3
向下规则
代码应该书写成自上而下的自然阅读顺序
缩进
摘录《代码整洁之道》
•   在 20 世纪 80 年代,常说函数不该长于一屏(那时候显示屏分辨率低,只有
    24 行)


•   函数应该有多短小 ? 通常来说,应该短于代码清单 3-2 中的函数 , 代码清单
    3-2 实在应该缩短成代码清单 3-3 这个样子


备注:我数了数清单 3-2 ,代码行数是 14 行, 而 3-3 是 6 行, 而且是包含最
 后的大括号的
摘录《软件开发沉思录》
• 方法只使用一级缩进
• 拒绝使用 else 关键字
• 一句代码只有一个 '.'
• 不要使用缩写
可读性-意
• 统一词汇
• 书写方式
统一词汇
代码是用来交流的,如果是这样,使用统一且一致的词汇就能提
 高代码的可读性
例1
中文站 html 页面中的一些词汇

#doc, #header, #content, #footer
topbar, masthead, alitalk, floatlogin 等等
例 2 -旺铺
例 3 -组件
使用同样的词汇书写和交流
action
• 希望我们具有一个统一的词汇库
• 在统一词汇的基础上,做到 twitter bootstrap 统一样式库让我
  们的 css 不必每次都从 0 开始
如何去写代码

代码即表达,所以我们 “怎么看就怎么写”


有了词汇,我们就有了描述的对象,然后使用代码将它表达
 出来
一个例子:选择产品组件
OfferChooser 由两部分组成
SourceOfferPart 主要由三部分组成

SearchPanel, OfferList, PagingNav
SearchPanel
由一个自定义的类目下拉框和普通的搜索功能组成
SelectedOfferPart
问题?
1. 开始仅知道必须要有 ChooserOffer 类, 因为这是由需求决定的。
  那 SearchPanel, PagingNav 等类 我怎么想得到呢 ? 不能全部都写在一个
 类中吗?
2. 类和类之间肯定有依赖,肯定有通信,那如何解决?
重构
重构是通向设计的一条平坦的小路
坏味道:长且重复的方法名
提取,形成 SearchPanel
现在的 ChooserOffer
代码行数和类大小

平均方法代码行数: 25 行
类中方法数量:保持 8 个以内
开发过程

          坏味道          坏味道          坏味道

   添加功能         重构           添加功能           重构


        原则-模式        原则-模式          原则-模式

                保持简单   不要重复 (DRY)




添加功能即“实现”
重构即设计
原则和模式
刚才的未解决问题:
类和类之间肯定有依赖,肯定有通信,那如何解决?
类和类的关系
1. 继承
2. 组合
类图
继承-单例
继承-多例
组合
原则
优先使用组合,而不是继承
( prefer composition over inheritance )


继承带来很强的耦合性,特别是在强类型语言中
在 JS 中,继承的耦合会低一些
根据耦合性对继承进行分类

扩展或 mixin
根据耦合性对继承进行分类

重写( override )
更适合 JS 的原则
“ 优先使用组合或 minin, 少用 override”

应该记住的:
一个类能否被继承是一个设计问题,而不是捡到便宜


除此外:
继承是否合理是否必要,可以看原则: LSP (里氏替换原则)
稳定依赖原则( DIP )

解决依赖性


实际上这个原则被称为 “依赖倒置原则”, 为了更好地理解,我弱化了这个原
 则


“ 模块应该依赖于比它更稳定的模块”


思考:
fdev4, core, widget, ui-core


应用: global module page
问题?
那稳定的类要调用非稳定的类,或者模块和模块之间需要通信怎么办 ?


我们引入一个中间层(思考 $.ajax 的回调和 自定义事件)
实现
依赖注入( DI )
引入间接层:使用自定义事件
[摘录]《敏捷软件开发,原则模式和实践》

a. 高层模块不应该依赖于低层模块。二者都应该依赖于抽象
b. 抽象不应该依赖于细节。细节应该依赖于抽象。
摘录
任何问题都可以通过引入一个中间层来解决


分层原则第一定律:不要分层


如果你知道自己在做什么, 3 层就足够了。
如果你不知道自己在做什么, 17 层也没用
开放封闭原则( OCP )
解决扩展性


“Closed for Modification; Open for Extension”
对变更关闭,对扩展开放
解析 OCP
这个原则不是教我们怎么做, 而是教我们做成怎么样


我们应该把模块写成:
只要添加代码就能完成扩展, 而不需要修改原来的代码
一个例子
再一个例子
问题
难道我一开始就写成那样吗? OCP?


重构:受一次伤原则
总结
方法组成代码“一级结构”。
长度短,名称精炼,向下规则


类以及类之间的关系,组成代码的“二级结构”
五大原则( DIP , OCP ,),以及我们未接触的 LSP SRP ISP


优先使用组合和 mixin 扩展等


重构坏味道: 1 太长, 2 受伤


类和类形成包,包以及包之间的关系,组成代码的“三级结构”


遵循共同的原则: 简单 / 没有重复
模式新视角
设计模式是一套词汇
我们对 Offer 进行一个排序,只要实现这个 Compare 接口就行了, 我们原来有
 这样的实现的,只是接口形式不一样,所以我们做个 Adapter 就好了


我们在取数上引入了 cache ,但我想让调用方透明,我们引入一个 Proxy...


我们还是要使用原来的那些方法的,但是太多了,我们做一个小小的 Facade,
 这样我们就不用管原来那堆东西了


矣~~,这个类构造太麻烦了,弄个 Factory 方便构造,同时把依赖注入,
还有还有, 这两个类的依赖不行,使用一个接口或者 Observer 反转一下依赖


嗯,这一系列操作,我们把它弄成一个一个 Command 序列化掉 ... 存起来,下
 次恢复再执行


这个验证框架扩展起来不是很方便,验证逻辑其实就是一个一个 Strategy 嘛,
 改改~~
重意不重形
看一个模式时,只要看它的“意图”,“遵循的原则”,还有“名称”


稍微看一下实现,看看能否用其他更优雅的实现,然后把类图和实现忘掉


使用时,突然感觉到自己正在使用某种模式, 这样就可以了。
即不经意间使用模式


重要的是知道什么时候不使用它
最后一个例子
http://fd.aliued.cn/doc/page/.personal/qijun.weiqj/design
画出类图
策略( Strategy 或 Policy)

原则?
开放封闭原则 OCP
依赖倒置原则 DIP
单一职责原则 SRP (一个类只有一个引起它变化的原因)


优先使用组合,而不是继承
prefer composition over inheritance
回顾
可读性
  形: 方法小,向下规则
  意: 词汇, 分层描述
原则
  依赖倒置(稳定依赖)原则 DIP
  开放封闭原则 OCP
重构
  方法太长,类太长 ...
  受一次伤原理
模式
  设计模式是一套用于交流的词汇
  策略模式 (Strategy)

More Related Content

Similar to 重构——关于可读性、原则和模式

腾讯大讲堂05 面向对象应对之道
腾讯大讲堂05 面向对象应对之道腾讯大讲堂05 面向对象应对之道
腾讯大讲堂05 面向对象应对之道
areyouok
 
jQuery使用技巧
jQuery使用技巧jQuery使用技巧
jQuery使用技巧
fangdeng
 
J query使用技巧
J query使用技巧J query使用技巧
J query使用技巧
fangdeng
 
Java Api Design
Java Api DesignJava Api Design
Java Api Design
yiditushe
 
2006 recycle opensourceprojects
2006 recycle opensourceprojects2006 recycle opensourceprojects
2006 recycle opensourceprojects
George Ang
 
Recycle Open Source Projects
Recycle Open Source ProjectsRecycle Open Source Projects
Recycle Open Source Projects
George Ang
 
Ibmzf2
Ibmzf2Ibmzf2
Ibmzf2
daoopp
 
01 orm概述及持久化介绍
01 orm概述及持久化介绍01 orm概述及持久化介绍
01 orm概述及持久化介绍
Zelin Wang
 
Android最佳实践
Android最佳实践Android最佳实践
Android最佳实践
supernlee
 
Java SE 7 技術手冊投影片第 06 章 - 繼承與多型
Java SE 7 技術手冊投影片第 06 章 - 繼承與多型Java SE 7 技術手冊投影片第 06 章 - 繼承與多型
Java SE 7 技術手冊投影片第 06 章 - 繼承與多型
Justin Lin
 
招聘笔试题(二)
招聘笔试题(二)招聘笔试题(二)
招聘笔试题(二)
yiditushe
 
常用JAVA代码质量静态检查工具
常用JAVA代码质量静态检查工具常用JAVA代码质量静态检查工具
常用JAVA代码质量静态检查工具
dearhwj
 

Similar to 重构——关于可读性、原则和模式 (20)

淘宝网前端开发面试题
淘宝网前端开发面试题 淘宝网前端开发面试题
淘宝网前端开发面试题
 
腾讯大讲堂05 面向对象应对之道
腾讯大讲堂05 面向对象应对之道腾讯大讲堂05 面向对象应对之道
腾讯大讲堂05 面向对象应对之道
 
腾讯大讲堂05 面向对象应对之道
腾讯大讲堂05 面向对象应对之道腾讯大讲堂05 面向对象应对之道
腾讯大讲堂05 面向对象应对之道
 
jQuery使用技巧
jQuery使用技巧jQuery使用技巧
jQuery使用技巧
 
J query使用技巧
J query使用技巧J query使用技巧
J query使用技巧
 
安卓中的设计模式举例 by hjm1fb
安卓中的设计模式举例 by hjm1fb安卓中的设计模式举例 by hjm1fb
安卓中的设计模式举例 by hjm1fb
 
Java Api Design
Java Api DesignJava Api Design
Java Api Design
 
N-layer design & development
N-layer design & developmentN-layer design & development
N-layer design & development
 
2006 recycle opensourceprojects
2006 recycle opensourceprojects2006 recycle opensourceprojects
2006 recycle opensourceprojects
 
Recycle Open Source Projects
Recycle Open Source ProjectsRecycle Open Source Projects
Recycle Open Source Projects
 
Ibmzf2
Ibmzf2Ibmzf2
Ibmzf2
 
01 orm概述及持久化介绍
01 orm概述及持久化介绍01 orm概述及持久化介绍
01 orm概述及持久化介绍
 
尼古丁加咖啡因,不瞌睡的简报設計模式 (Caffeine+Nicotine)
尼古丁加咖啡因,不瞌睡的简报設計模式 (Caffeine+Nicotine)尼古丁加咖啡因,不瞌睡的简报設計模式 (Caffeine+Nicotine)
尼古丁加咖啡因,不瞌睡的简报設計模式 (Caffeine+Nicotine)
 
Android最佳实践
Android最佳实践Android最佳实践
Android最佳实践
 
getPDF.aspx
getPDF.aspxgetPDF.aspx
getPDF.aspx
 
getPDF.aspx
getPDF.aspxgetPDF.aspx
getPDF.aspx
 
Java DSL与动态代码生成技术的应用 (上集:DSL部分)
Java DSL与动态代码生成技术的应用 (上集:DSL部分)Java DSL与动态代码生成技术的应用 (上集:DSL部分)
Java DSL与动态代码生成技术的应用 (上集:DSL部分)
 
Java SE 7 技術手冊投影片第 06 章 - 繼承與多型
Java SE 7 技術手冊投影片第 06 章 - 繼承與多型Java SE 7 技術手冊投影片第 06 章 - 繼承與多型
Java SE 7 技術手冊投影片第 06 章 - 繼承與多型
 
招聘笔试题(二)
招聘笔试题(二)招聘笔试题(二)
招聘笔试题(二)
 
常用JAVA代码质量静态检查工具
常用JAVA代码质量静态检查工具常用JAVA代码质量静态检查工具
常用JAVA代码质量静态检查工具
 

重构——关于可读性、原则和模式