课程简介
软件开发往往大部分时候面对的是既有系统的二次开发,维护遗留系统。随着系统的不断升级,需要维护的遗留系统的代码也越来越多。在这个过程中,二次开发的工程师,往往会非常痛苦,会遇到添加新功能困难、修改bug困难,甚至不的不面对推翻之前的遗留系统,重新来过。导致开发效率极其低下,并且成本很高,系统很不稳定。所以重构也就在所难免。所有的软件系统将来都会变成遗留系统,并且都可能会遭遇性能越来越低下、稳定行越来越差等情况,因此软件开发人员不得不面对既有系统的各种问题,本课程正是告诉你如何重构既有的遗留系统, 如何重构代码,重构设计,重构架构。
培训客户:
包括:阿里(杭州总部)2次、京东(北京总部)2次、平安银行(2次)、中金在线、洛基亚(4次)、IBM、HP公司、杭州恒生电子、用友软件、中国电信、中石油、西南电信、中国移动、上海盛大网络、厦门航空、通化钢铁集团、总参等近百家企事业单位。
目标收益
培训对象
各类软件研发中心的软件设计师、架构师, 项目经理,技术总监,质量部门经理,开发人员,对重构技术怀有疑问和困惑,需要梳理解答的团队和个人,效果最佳。
课程大纲
第一单元 认识优秀的系统及劣质系统,建立重构意识 |
内容一:建立构建优秀系统的思维 1.优秀的系统有什么特征 2.劣质代码有什么特征 3.劣质代码的代价 4.为什么很多程序员都讨厌阅读别人的代码? 5.如何阅读别人的系统? 6.如何写出简练,易于理解,模块化,层次性,设计良好,高效,优雅,并且清晰的系统。 内容二:软件系统开始坏死的症状 1.硬化Rigidity——系统变得越来越难以变更,修复或增添新功能的代价高昂; 2.脆弱Fragility——对系统的任何哪怕是微小的变更都可能造成四处(甚至是与变更处没有逻辑上的关联之处的崩溃; 3.绑死Immobility——抽取系统的任何部分用来复用都非常困难; 4.胶着Viscosity——以与原有设计保持一致的方式来对实施变更已经非常困难,诱使开发人员绕过它选择容易但有害的途径,其结果却使系统死的更快。 5.案例:阅读一段烂代码,分析其对系统的危害。 内容三:建立重构的思想 1.重构与添加新功能的关系。 2.不要在同一个地方跌倒两次(何时重构? 增加新功能时;修补错误时;Review码时一并重构) 3.重构与重写的取舍(系统实在混乱怎么办?) 4.如何保证重构的正确。 5.代码、类、组件、子系统、系统、大型分布式系统的重构联系及区别 6.重构与设计的关系 7.通过案例,演示某系统片段,展示重构的基本思想(一个好的结构是如何做到系统论的可扩展性;以及如何将混乱的代码重构到一个好的结构) 内容四:案例—通过实际项目演示重构 1.介绍项目需求情况,进行设计 2.阅读代码指出代码坏症状 3.通过重构逐步改善代码质量 |
第二单元 代码的坏味道的指标及特点,以及应对的重构之道 |
内容一:重构关键—发现代码的坏味道 1.模块的高扇入与低扇出 2.圈复杂度在项目中的实用价值 3.语句的平均长度——论述其深层含义(函数不需要故意写得短小,清晰的代码自然短小;当长则长与当短则短) 4.函数参数个数的辩证 5.标识参数----丑陋不堪、骇人听闻的做法? 6.Ward Cunningham原则——深合己意的例程 7.“每个函数只做一件事”与“每个函数一个抽象层级”(程序员往往很难学会遵循这条规则,写出只停留于一个抽象层级上的函数) 8.Switch-case语句——程序设计的万恶之源? 9.“指令与查询分离”的意义。 10.Try/Catch代码块 11.重复的代码/模块 12.可以根据客户现在的项目作为案例进行现场分析,找出相应的代码坏味道 内容二:某项目分析----重点了解现实项目代码的充斥大量坏味道 1.介绍项目需求情况,阅读现有代码指出代码坏症状 2.不看不知道,代码到底有多烂—触目惊心的代码 3.通过重构逐步改善代码质量 4.本案例学习多种重构方式 |
第三单元 重构实践 |
内容一:重构初步:识别编码中的坏味道 1.重复的代码 2.过大的类及过长的函数 3.耦合:依恋情结、数据泥团及过度耦合的消息链 4.分散的逻辑:发散的变化及霰弹式的修改 5.复杂的逻辑:switch现象及平行继承体系 6.其它:中间人、数据类、不佳的继承 内容二:重构实践:面向对象及领域驱动 1.将过程化设计转化为对象设计,并讨论过程化设计与对象化设计的特点及历史博弈;并给出过程式设计及及对象设计的模式——合适的就是好的! 2.封装值域/自封装值域的重构 3.以数据类取代记录的策略 4.以对象取代数组的策略 5.以类取代型别码——Replace Type Code with Class 6.以子类取代型别码——Replace Type Code with Subclasses 7.以值域取代子类——Replace Subclass with Fields 8.建模为属性与建模为对象——系统建模中的微妙变化 9.Data Class——纯粹的数据类 10.以State/Strategy取代型别码 11.通过案例介绍函数的重构 内容三:重构实践—复杂条件表达式重构 1.常见问题,如何处理让人疯狂的复杂分类? 2.以多态取代条件式——Replace Conditional with Polymorphism 3.提炼继承体系——Extract Hierarchy 4.塑造模板函数——Form Template Method 5.以委托取代继承——Replace Inheritance with Delegation 6.以继承取代委托——Replace Delegation with Inheritance 7.用Strategy替换条件逻辑 8.用Bridge组合动态变化 9.用State替换状态改变条件语句 10.用Composite替换隐含树 11.用Command替换条件调度程序 12.在多态体系中,如何处理子条件不一致的情况——继承体系中的高级技巧。 内容四:重构实践—去除“大泥球”式的设计 1.过大的函数、模块、子系统 2.依恋情结、数据泥团 3.从系统设计的角度分析混乱产生的原因 4.通过案例介绍如何分解系统 内容五:重构实践—职责单一 1.一个模块完成一个职责——子模块位于同一个抽象层次 2.功能函数与逻辑函数的分离 3.Divergent Change——发散的变化 1.Shotgun Surgery——散弹枪式的修改 |
第四单元 重构不是万能的——系统的重构及预先设计的技巧 |
内容一:重构的优势与局限 1.重构的优势与局限 2.预先设计与重构 3.代码重构与系统重构的异同 4.逐渐演化的系统及其特点 5.对大型遗留的系统的处理 6.分析某大型系统,如何设计重构及逐演化,以及我们在实际项目中何去何从。 内容二:什么是好的设计以及如何预先设计实现 1.什么是好的设计和衡量的手段 2.可伸缩性(Scalable)软件能够在用户的使用率、用户的数目增加很快的情况下,保持合理的性能。 3.可扩展性(Extensibility)一个软件系统应当允许导入新技术/功能而不引起原有系统大的变化。 结合案例,通过那些手段如何实现该目标 4.灵活性(Flexibility)修改或改进一个已投入运行的软件所需工作量的大小。 结合案例,通过那些手段如何实现该目标 5.可维护性(maintainability):为满足用户新的要求,或当环境发生了变化或运行中发现了新的错误时,对一个已投入运行的软件进行相应诊断和修改所需工作量的大小。 6.可复用性(Reusability)一个软件或其部件能再次用于其他应用的程度。 7.软件的变化分析---发现变化/封装变化/隔离变化 8.分析真实项目,如何预先设计,给我们哪些启示,我们可以学习到什么 内容三:系统设计中的关键因素 1.抽象(Abstraction)、封装(Encapsulation)和信息隐藏(Information Hiding) 2.分而治之(Divide-And-Conquer)和模块化(modularization) 3.策略和实现的分离(Separation of Policy and Implementation) 4.接口和实现的分离(Separation of Interface and Implementation) 5.单一引用点(Single Point of Reference) 内容四:案例—某项目设计重构案例分析 1.案例情况 2.演示如何发现设计坏味道,以及如何重构 |
第五单元 模式与重构实践 |
内容一:模式在重构中的重要地位 1.重构时,如何做到有章可循 2.设计模式概述 3.设计模式的学习阶段及特点 4.设计模式的本质论! 5.设计模式如何适应变化和封装 6.重构到模式的思路 内容二:实践---系统中复杂条件/行为及其动态变化的应对之策 1.分析案例,深入讨论下列模式的精髓,及其在重构中的实际运用 2.用Strategy替换条件逻辑 3.用Bridge组合动态变化 4.用State替换状态改变条件语句 5.用Composite替换隐含树 6.用Command替换条件调度程序 7.重点学习案例的重构到模式的过程 内容三:实践---如何设计统一且抽象的抽象的系统 1.分析案例,深入讨论下列模式的精髓,及其在重构中的实际运用 2.形成Template Method 3.提取Composite 4.用Composite替换一/多之分 5.用Observer替换硬编码的通知 6.通过Adapter统一接口 7.重点学习案例的重构到模式的过程 内容四:实践---如何设计稳定的系统——保护系统的核心不 受变化的影响 1.分析案例,深入讨论下列模式的精髓,及其在重构中的实际运用 2.用类替换类型代码 3.将装饰功能搬移到Decorator 4.用Visitor限制新增功能对流程的影响 5.用Singleton限制实例化 6.引入Null Object 7.转移聚集操作到Collecting Parameter 8.重点学习案例的重构到模式的过程 内容五:实践------案例练习,模式的综合运用及分析讨论 1.分析案例,深入讨论下列模式的精髓,及其在重构中的实际运用 2.案例分析,背景介绍 3.找出系统改设计的关键点 4.用Strategy设定系统的稳定点 5.业务逻辑层对功能的引用要点 6.以Abstract Factory模式进行初始组装——兼讨论分层的要点 7.以Bridge模式应对其他因素的变化 8.以producer - consumer design pattern处理海量数据及长任务 9.重点学习案例的重构到模式的过程 |
第六单元 系统与大型系统的演化及重构实践 |
内容一: 架构重构 1.软件架构概述 2.遗留系统的软件架构恢复 3.软件架构的重构时机 4.软件架构的重构步骤 5.架构坏味道 6.架构重构策略 内容二:大型系统的演化及核心技术 7.应用服务和数据服务分离 8.使用缓存改善数据库瓶颈 9.使用应用服务器集群和负载均衡避免运用服务器瓶颈 10.数据库读写分离 11.用CDN及分布式文件系统加速系统响应 12.分布式数据库系统及NoSQL运用 13.进行横向的业务拆分 14.分布式服务,打造自己的软件生态环境 内容三:案例分析—某互联网项目1架构重构及演化 1.项目背景以及相关需求 2.初始上线:当前的最佳策略 3.物理部署分离 4.数据库瓶颈的解决1:引入读写分离 5.系统开发框架的更迭 6.系统演化中的走过的弯路1:纵向加强的不归路 7.数据库瓶颈的解决2:引入搜索引擎 8.引入分布式文件系统 9.引入分布式缓存 10.引入分布式服务框架,服务拆分 11.引入分布式消息中间件 12.引入分布式Session框架 内容四:案例分析—某互联网项目2平台架构重构 1.项目背景以及相关需求 2.从单机版、简单网络版、分布式网络版、重构后的大型分布式网络版的历程 3.架构设计及重构中的多因素综合考虑及其影响 4.原有系统的不足分析 5.分布式系统中多中心与单中心的演变过程及博弈分析 6.引入CDN分布式文件服务系统 7.从数据库中dump,独立部署图像服务器 8.引入Memcache缓存,缓解数据库服务器 9.引入云服务与云存储,及其博弈 10.引入基于lucene的全文检索,缓解数据库服务器 11.系统抽象与服务抽取 12.服务隔离及负载均衡:nginx及lvs运用 13.基础服务与运用服务的抽取与分离 |
第一单元 认识优秀的系统及劣质系统,建立重构意识 内容一:建立构建优秀系统的思维 1.优秀的系统有什么特征 2.劣质代码有什么特征 3.劣质代码的代价 4.为什么很多程序员都讨厌阅读别人的代码? 5.如何阅读别人的系统? 6.如何写出简练,易于理解,模块化,层次性,设计良好,高效,优雅,并且清晰的系统。 内容二:软件系统开始坏死的症状 1.硬化Rigidity——系统变得越来越难以变更,修复或增添新功能的代价高昂; 2.脆弱Fragility——对系统的任何哪怕是微小的变更都可能造成四处(甚至是与变更处没有逻辑上的关联之处的崩溃; 3.绑死Immobility——抽取系统的任何部分用来复用都非常困难; 4.胶着Viscosity——以与原有设计保持一致的方式来对实施变更已经非常困难,诱使开发人员绕过它选择容易但有害的途径,其结果却使系统死的更快。 5.案例:阅读一段烂代码,分析其对系统的危害。 内容三:建立重构的思想 1.重构与添加新功能的关系。 2.不要在同一个地方跌倒两次(何时重构? 增加新功能时;修补错误时;Review码时一并重构) 3.重构与重写的取舍(系统实在混乱怎么办?) 4.如何保证重构的正确。 5.代码、类、组件、子系统、系统、大型分布式系统的重构联系及区别 6.重构与设计的关系 7.通过案例,演示某系统片段,展示重构的基本思想(一个好的结构是如何做到系统论的可扩展性;以及如何将混乱的代码重构到一个好的结构) 内容四:案例—通过实际项目演示重构 1.介绍项目需求情况,进行设计 2.阅读代码指出代码坏症状 3.通过重构逐步改善代码质量 |
第二单元 代码的坏味道的指标及特点,以及应对的重构之道 内容一:重构关键—发现代码的坏味道 1.模块的高扇入与低扇出 2.圈复杂度在项目中的实用价值 3.语句的平均长度——论述其深层含义(函数不需要故意写得短小,清晰的代码自然短小;当长则长与当短则短) 4.函数参数个数的辩证 5.标识参数----丑陋不堪、骇人听闻的做法? 6.Ward Cunningham原则——深合己意的例程 7.“每个函数只做一件事”与“每个函数一个抽象层级”(程序员往往很难学会遵循这条规则,写出只停留于一个抽象层级上的函数) 8.Switch-case语句——程序设计的万恶之源? 9.“指令与查询分离”的意义。 10.Try/Catch代码块 11.重复的代码/模块 12.可以根据客户现在的项目作为案例进行现场分析,找出相应的代码坏味道 内容二:某项目分析----重点了解现实项目代码的充斥大量坏味道 1.介绍项目需求情况,阅读现有代码指出代码坏症状 2.不看不知道,代码到底有多烂—触目惊心的代码 3.通过重构逐步改善代码质量 4.本案例学习多种重构方式 |
第三单元 重构实践 内容一:重构初步:识别编码中的坏味道 1.重复的代码 2.过大的类及过长的函数 3.耦合:依恋情结、数据泥团及过度耦合的消息链 4.分散的逻辑:发散的变化及霰弹式的修改 5.复杂的逻辑:switch现象及平行继承体系 6.其它:中间人、数据类、不佳的继承 内容二:重构实践:面向对象及领域驱动 1.将过程化设计转化为对象设计,并讨论过程化设计与对象化设计的特点及历史博弈;并给出过程式设计及及对象设计的模式——合适的就是好的! 2.封装值域/自封装值域的重构 3.以数据类取代记录的策略 4.以对象取代数组的策略 5.以类取代型别码——Replace Type Code with Class 6.以子类取代型别码——Replace Type Code with Subclasses 7.以值域取代子类——Replace Subclass with Fields 8.建模为属性与建模为对象——系统建模中的微妙变化 9.Data Class——纯粹的数据类 10.以State/Strategy取代型别码 11.通过案例介绍函数的重构 内容三:重构实践—复杂条件表达式重构 1.常见问题,如何处理让人疯狂的复杂分类? 2.以多态取代条件式——Replace Conditional with Polymorphism 3.提炼继承体系——Extract Hierarchy 4.塑造模板函数——Form Template Method 5.以委托取代继承——Replace Inheritance with Delegation 6.以继承取代委托——Replace Delegation with Inheritance 7.用Strategy替换条件逻辑 8.用Bridge组合动态变化 9.用State替换状态改变条件语句 10.用Composite替换隐含树 11.用Command替换条件调度程序 12.在多态体系中,如何处理子条件不一致的情况——继承体系中的高级技巧。 内容四:重构实践—去除“大泥球”式的设计 1.过大的函数、模块、子系统 2.依恋情结、数据泥团 3.从系统设计的角度分析混乱产生的原因 4.通过案例介绍如何分解系统 内容五:重构实践—职责单一 1.一个模块完成一个职责——子模块位于同一个抽象层次 2.功能函数与逻辑函数的分离 3.Divergent Change——发散的变化 1.Shotgun Surgery——散弹枪式的修改 |
第四单元 重构不是万能的——系统的重构及预先设计的技巧 内容一:重构的优势与局限 1.重构的优势与局限 2.预先设计与重构 3.代码重构与系统重构的异同 4.逐渐演化的系统及其特点 5.对大型遗留的系统的处理 6.分析某大型系统,如何设计重构及逐演化,以及我们在实际项目中何去何从。 内容二:什么是好的设计以及如何预先设计实现 1.什么是好的设计和衡量的手段 2.可伸缩性(Scalable)软件能够在用户的使用率、用户的数目增加很快的情况下,保持合理的性能。 3.可扩展性(Extensibility)一个软件系统应当允许导入新技术/功能而不引起原有系统大的变化。 结合案例,通过那些手段如何实现该目标 4.灵活性(Flexibility)修改或改进一个已投入运行的软件所需工作量的大小。 结合案例,通过那些手段如何实现该目标 5.可维护性(maintainability):为满足用户新的要求,或当环境发生了变化或运行中发现了新的错误时,对一个已投入运行的软件进行相应诊断和修改所需工作量的大小。 6.可复用性(Reusability)一个软件或其部件能再次用于其他应用的程度。 7.软件的变化分析---发现变化/封装变化/隔离变化 8.分析真实项目,如何预先设计,给我们哪些启示,我们可以学习到什么 内容三:系统设计中的关键因素 1.抽象(Abstraction)、封装(Encapsulation)和信息隐藏(Information Hiding) 2.分而治之(Divide-And-Conquer)和模块化(modularization) 3.策略和实现的分离(Separation of Policy and Implementation) 4.接口和实现的分离(Separation of Interface and Implementation) 5.单一引用点(Single Point of Reference) 内容四:案例—某项目设计重构案例分析 1.案例情况 2.演示如何发现设计坏味道,以及如何重构 |
第五单元 模式与重构实践 内容一:模式在重构中的重要地位 1.重构时,如何做到有章可循 2.设计模式概述 3.设计模式的学习阶段及特点 4.设计模式的本质论! 5.设计模式如何适应变化和封装 6.重构到模式的思路 内容二:实践---系统中复杂条件/行为及其动态变化的应对之策 1.分析案例,深入讨论下列模式的精髓,及其在重构中的实际运用 2.用Strategy替换条件逻辑 3.用Bridge组合动态变化 4.用State替换状态改变条件语句 5.用Composite替换隐含树 6.用Command替换条件调度程序 7.重点学习案例的重构到模式的过程 内容三:实践---如何设计统一且抽象的抽象的系统 1.分析案例,深入讨论下列模式的精髓,及其在重构中的实际运用 2.形成Template Method 3.提取Composite 4.用Composite替换一/多之分 5.用Observer替换硬编码的通知 6.通过Adapter统一接口 7.重点学习案例的重构到模式的过程 内容四:实践---如何设计稳定的系统——保护系统的核心不 受变化的影响 1.分析案例,深入讨论下列模式的精髓,及其在重构中的实际运用 2.用类替换类型代码 3.将装饰功能搬移到Decorator 4.用Visitor限制新增功能对流程的影响 5.用Singleton限制实例化 6.引入Null Object 7.转移聚集操作到Collecting Parameter 8.重点学习案例的重构到模式的过程 内容五:实践------案例练习,模式的综合运用及分析讨论 1.分析案例,深入讨论下列模式的精髓,及其在重构中的实际运用 2.案例分析,背景介绍 3.找出系统改设计的关键点 4.用Strategy设定系统的稳定点 5.业务逻辑层对功能的引用要点 6.以Abstract Factory模式进行初始组装——兼讨论分层的要点 7.以Bridge模式应对其他因素的变化 8.以producer - consumer design pattern处理海量数据及长任务 9.重点学习案例的重构到模式的过程 |
第六单元 系统与大型系统的演化及重构实践 内容一: 架构重构 1.软件架构概述 2.遗留系统的软件架构恢复 3.软件架构的重构时机 4.软件架构的重构步骤 5.架构坏味道 6.架构重构策略 内容二:大型系统的演化及核心技术 7.应用服务和数据服务分离 8.使用缓存改善数据库瓶颈 9.使用应用服务器集群和负载均衡避免运用服务器瓶颈 10.数据库读写分离 11.用CDN及分布式文件系统加速系统响应 12.分布式数据库系统及NoSQL运用 13.进行横向的业务拆分 14.分布式服务,打造自己的软件生态环境 内容三:案例分析—某互联网项目1架构重构及演化 1.项目背景以及相关需求 2.初始上线:当前的最佳策略 3.物理部署分离 4.数据库瓶颈的解决1:引入读写分离 5.系统开发框架的更迭 6.系统演化中的走过的弯路1:纵向加强的不归路 7.数据库瓶颈的解决2:引入搜索引擎 8.引入分布式文件系统 9.引入分布式缓存 10.引入分布式服务框架,服务拆分 11.引入分布式消息中间件 12.引入分布式Session框架 内容四:案例分析—某互联网项目2平台架构重构 1.项目背景以及相关需求 2.从单机版、简单网络版、分布式网络版、重构后的大型分布式网络版的历程 3.架构设计及重构中的多因素综合考虑及其影响 4.原有系统的不足分析 5.分布式系统中多中心与单中心的演变过程及博弈分析 6.引入CDN分布式文件服务系统 7.从数据库中dump,独立部署图像服务器 8.引入Memcache缓存,缓解数据库服务器 9.引入云服务与云存储,及其博弈 10.引入基于lucene的全文检索,缓解数据库服务器 11.系统抽象与服务抽取 12.服务隔离及负载均衡:nginx及lvs运用 13.基础服务与运用服务的抽取与分离 |