®Evolvebycase我们来看设计前言架构的输出=详细设计的输入(结构视图)一个菜鸟的代码成长过程什么是优秀的设计?做设计的一些基本法则?为什么要重构?如何重构?重构遇到的问题,如何去解决我们所处的位置——需求/架构/设计关系架构的输出=详细设计的输入功能视图开发视图实现视图数据视图场景视图消费者:客户/用户/开发组织管理者视角:系统的功能元素,以及它们的接口,职责,交互主要元素:系统,子系统,功能模块,子功能模块,接口用途:开发组织划分,成本/进度的评估缺陷:现有系统没有该视图。功能视图功能视图-实例开发视图消费者:开发相关人员/测试人员视角:系统如何开发实现主要元素:描述系统的层,分区,包,框架,系统通用服务,业务通用服务,类和接口,系统平台和相关基础框架。用途:指导开发组织设计和开发实现。开发视图-实例实现视图消费者:开发相关人员/测试人员/实施人员视角:系统交付物结构形式和相关实现规范主要元素:创建可交付物的形式(网页、dll、可执行文件、源码)以及组织结构开发过程中必须遵守的相关规范和指南用途:实现视图-实例数据视图消费者:数据架构师/开发相关人员视角:系统数据模型以及数据存储/存取等主要元素:系统的核心实体模型以及相应的数据存储模型和存储方式系统的数据存取相关策略系统核心的数据流用途:模型的选择会影响最终生产系统的灵活性和可重用性MartinFowler数据视图-数据存储策略在159项目中,数据集成过程中就需要一个前期规划,其他项目是不是也有相关问题那?数据视图-处理流程场景视图消费者:设计和开发人员视角:概括了架构上最重要的场景(最典型或者最有风险)及其非功能性需求,通过这些场景的实现,阐明了架构的广度或众多架构元素运行的方式。主要元素:用途:总结一下详细设计从架构那里可以榨取以上信息,前提条件是架构师在设计完后一定要排除技术风险,并且进行测试视情况而定,不是所有信息都必须榨取,适可而止架构方面大家有什么疑问,等到我们是架构的时候共同探讨,谢谢!架构的输出暂时就这么多我们来看一下代码的成长过程-log系统概述项目背景开始使用java编程语言,是第一个面向对象项目,以前仅仅使用C语言,结构化思维方式需求项目经理,告诉编写一个Log类,进行打印输出系统log信息一条Log包含时间,线程ID,log编号,Message信息(必须)输出到文件我们来看一下代码的成长过程-原始版我们来看一下代码的成长过程需求变化1_日志级别和两种输出方式一条log包含时间,线程id,log编号,级别,Message信息(必须)Log定义几个级别(debug,information,warining,error)两种输出方式:•1:level为info,debug的直接输出到console•2:其他级别输出到File中需求变更1对应代码状态我们来看一下代码的成长过程需求变化2_log输出有两种格式一种是原来的直接文本格式新增一个专门格式,供后台的监控和分析系统进行及时分析,暂定为xml格式需求变更2对应代码状态需求变化3-输出目的地和日志格式化更复杂同一条Log可以输出到多种目的地同一条Log可以有多种格式化输出目的地条件更复杂每一种目的地,都可能多种选择格式化的一种需求变更3对应代码状态这种做法如果需求变更会导致什么如果增加一种新目的地(比如SocketServer,JMS)如果增加一种格式化(比如固定化)如果条件变化会怎样?我们想象一下代码现在长成什么样子了?你有什么好的想法去改变这种状态?它是不是应该减肥了?是不是管的太宽了?听听大家的意见设计和编码的关系边设计边编码,想法全在大脑内存中先设计后编码不拘泥设计表现形式(白板、草稿纸均可),目的让别人了解你的想法。这个过程是迭代的。只做设计,编码留给开发人员什么是优秀设计?--关注软件的可维护性和可复用性好的设计目标可扩展性:新的功能可以很容易地加入到系统之中灵活性:可以允许代码修改平稳,而不会涉及到很多其他的模块可插入性:可以很容易的将一个类抽出去,同时将另一个有同样接口的类加入进来。为什么这是优秀的设计?——背景篇看一些数据业内统计数据显示,一个软件系统从开始到最终消亡的整个生命周期,前期的总代价是20~40%.绝大部分的工作重点,还需要花费在系统正式上线以后的后续维护和在系统的升级上。但是我们往往忽略了后期的系统可维护性。软件维护——残酷的现实程序员脑子里原先那些漂亮的设计随时间的推移会慢慢“发出腐化的臭味”。去年才构建好的漂亮小巧的系统,到了今年却变成了由一堆纠缠不清的函数和变量搅合在一起的“代码浆糊”。为什么会这样?迄今为止人们构建出的几乎所有软件系统都遭遇了缓慢的,不可抗拒的腐化,这种现象如此普遍。。。为什么这是优秀的设计?——背景篇什么原因导致的?有时候我们把原因归咎为客户,责怪他们总是更改需求。我们自我安慰地认为,只要客户的需求仅限于他们最初的声明的,那么我们的设计就是没问题的,所以错就错在客户改变了需求。有时候,我们也会埋怨老板,是他么没有给我们时间进行充分的分析。其实根本不存在充分分析这种东西。无论花费多少时间试图找出完美的软件结构,客户总是引入一个变化破坏这个结构,不存在完美结构,只存在哪些试图平衡当前代价和收益的结构。软件变更基本法则软件不断变更的法则:真实世界中使用的程序必须变更,否则它在环境中的作用就会越来越小。软件复杂增加性法则:随着一个不断演进程序的变更,它的结构会变得更复杂,除非通过积极的工作来避免这一现象。公司的现状:还没有考虑到软件的可维护性,以后应该多考虑考虑这点,不过目前的打捆式项目已经考虑到了可复用性为什么这是优秀的设计?——解救篇软件的可维护性和可复用性这就成为我们程序员苦苦追求的境界。寻找万能的上帝前人经过不断总结,发现和这些变化进行斗争,如果遵循某些法则,过程会变的很有趣,程序员不会暗无天日,系统不会动辄崩溃。我们找到了解救法宝——法则。为什么这是优秀的设计?——解救篇优秀设计第一法则——开闭原则何谓开闭原则?软件组成实体(类、模块、函数,等等)应该是可扩展的,但是不可修改的。(即软件实体可以通过增加代码实现扩展,但是不能修改已有代码)。如何实现开闭原则?——2个基本思想•共性和可变性分析•正确的接受现实——重构为什么这是优秀的设计?——解救篇共性可变性分析实现抽象:在oopl中,可以创建出固定却能描述一组任意个可能行为的抽象体,这个抽象就像抽象基类或者接口,任意可能的行为就是可能的派生类。针对接口(抽象)设计:由于模块之间依赖一个固定的抽象,所以它对更改可以是关闭的。注意抽象有度为什么这是优秀的设计?——重构篇正确的接受现实——重构面对复杂的领域多变性,设计师根据经验猜测程序可能遭遇的变化,如果猜测正确,获得成功;如果猜测错误,遭受失败。有时为了不必要的复杂性,我们会被愚弄(没有抽象)。但是当变化发生时,我们就应该创建抽象进行隔离以后的同类变化。(题外话:我们设计人员应该积极地参与到需求过程,这样我们的预测才有可能正确!)即对软件内部结构的一种调整,目的是不改变功能的前提下,提高其可理解性,降低其修改成本代码的坏味道与重构代码的坏味道概述坏味道解决之道-重构技术坏味道代码坏味道(codesmell),是指在代码之中潜在问题的警示信号.并非所有的坏味道所指示的确实是问题,但是对于大多数坏味道,均很有必要加以查看,并做出相应决定代码坏味道是需要重构的症状。或者潜在的问题(PotentialProblem)或者缺陷(Flaw)代码坏味道和拙劣设计相比是低的层次,重点在代码的层次生病的症状21种代码坏味道-1DuplicatedCode重复代码LongMethod过长方法LargeClass过长类LongParameterList过长参数列表DivergentChange发散式变化ShotgunSurgery霰弹式修改FeatureEnvy特性依恋DataClumps数据泥团PrimitiveObsession基本类型偏执SwitchStatementsswitch语句21种代码坏味道-2DataClass数据类RefusedBequest拒绝继承Comments注释过多TemporaryField临时字段MessageChains消息链MiddleMan中间人InappropriateIntimacy过度亲密LazyClass冗余类21种代码坏味道-3ParallelInheritanceHierarchies平行继承体系SpeculativeGenerality理论上的一般性AlternativeClasseswithDifferentInterfaces接口不同的等效类IncompleteLibraryClass不完整的库类21种代码坏味道_治疗手段软件重构—面临的困难程序员方面公司方面如何改变现状程序员方面不知道如何去重构,认识没有达到一定程度。程序员的认识有问题,认为别人写的垃圾都很垃圾不如自己写的,还不如将此功能块重新开发。个人误区,认为做新项目好,能学到新的东西,不喜欢维护旧项目,忽略了提高技能,而不是技巧。公司方面认为做出来东西才有价值,因为你做了两个月,可能界面和功能一点都没有变。公司没有那么多时间和精力让你去重构对项目的工期评估有问题:根据业界统计:其中一个项目从设计到上线运行,前期的总成本和工时只占软件总成本和总工时的20%-40%,后期占60%-80%。重构过程中,没有为公司带来直接的价格,不如新开发项目。如何改变现状尽量挤时间从设计开始就不断去重构,开发中更要重视重构,不要等到项目都要上线了,再去想着重构积极去面对重构下面看一个实际项目中重构的例子回顾架构的输出=详细设计的输入(结构视图)一个菜鸟的代码成长过程什么是优秀的设计?做设计的一些基本法则?为什么要重构?如何重构?重构遇到的问题,如何去解决?谢谢!!!