设计模式-2-从问题开始!长方形与正方形假如我们有一个类:长方形(Rectangle)我们需要一个新的类,正方形(Square)问:可否直接继承长方形?没问题,因为数学上正方形就是长方形的子类!-3-开始设计:正方形publicclassRectangle{privateintwidth;privateintheight;publicvoidsetWidth(intw){width=w;}publicintgetWidth(){returnwidth;}publicvoidsetHeight(inth){height=h;}publicintgetHeight(){returnheight;}}publicclassSquareextendsRectangle{publicvoidsetWidth(intw){super.setWidth(w);super.setHeight(w);}publicvoidsetHeight(inth){super.setWidth(h);super.setHeight(h);}}-4-设计方案正确吗?publicstaticvoidresize(Rectangler){while(r.getHeight()=r.getWidth()){r.setHeight(r.getHeight()+1);}System.out.println(“It’sOK.);}Rectangler1=newRectangle();r1.setHeight(5);r1.setWidth(15);resize(r1);Rectangler2=newSquare();r2.setHeight(5);r2.setWidth(15);resize(r2);使用父类(长方形)时,程序正常运行使用子类(正方形)时,程序陷入死循环设计出问题了?继承出问题了?-5-为什么会出现问题?违背了面向对象的设计原则!-6-违背Liskov替换原则Square类针对height、width添加了Rectangle所没有的附加的约束(即要求height=width),这样Square类(子类)不能完全替换Rectangle(父类)违背了Liskov替换原则带来潜在的设计问题(使用resize方法时,子类出错!)-7-怎么办?ABABCabstract在可能的情况下,由抽象类(接口)继承-8-抽象类与具体类具体类3抽象类1abstract抽象类2abstract具体类1抽象类3abstract具体类2只要有可能,不要从具体类继承。行为集中的方向是向上的(抽象类)数据集中的方向是向下的(具体类)-9-解决方案主要内容软件设计模式导论创建型模式结构型模式行为型模式11软件设计模式导论软件设计模式概念设计原则GoF的设计模式GoV的设计模式反模式12模式模式在现实生活中随处可见,模式是对成功应用经验的总结与复用。人们在自己的环境中不断发现问题和找寻问题的解决方案的时候,发现有一些问题及其解决方案不断变换面孔重复出现,在这些不同的面孔后面是共同的本质;这些共同的本质就是模式。如广东人的老火例汤:鲮鱼+?生鱼+?13模式14模式无处不在的模式好莱坞电影模式动作片、戏剧片、战争片、灾难片、恐怖片…古代行军布阵八卦阵、鸳鸯阵、天门阵…建筑、服装、交通、文化….等领域诸多模式模式的起源模式思想最初形成于建筑学。1977年,建筑大师Alexander出版了《APatternLanguage:Towns,Building,Construction》一书。该书描述了城镇、邻里、住宅、花园和房间等253种设计建筑物的模式。模式理论大师ChristopherAlexander给出的模式定义:模式是某外在环境(Context)下,对特定问题(Problem)的惯用解决方案(Solution)。设计模式在软件设计行业中的起源可以追溯到1987年。受Alexander著作的影响,KentBeck和WardCunningham在1987年举行的一次面向对象的会议上发表了论文:《在面向对象编程中使用模式》。目前,被公认在设计模式领域最具影响力的著作是ErichGamma、RichardHelm、RalphJohnson和JohnVlissides在1995年合作出版的著作:《DesignPatterns:ElementsofReusableObject-OrientedSoftware》设计模式18设计模式(中译本《设计模式:可复用的面向对象软件的基本原理》或《设计模式》),该书被广大喜爱者昵称为GOF(GangofFour)“四人帮”之书,被认为是学习设计模式的必读著作,GOF之书已经被公认为是设计模式领域的奠基之作。广义讲,软件设计模式是可解决一类软件问题并能重复使用的软件设计方案狭义讲,设计模式是对被用来在特定场景下解决一般设计问题的类和相互通信的对象的描述。是在类和对象的层次描述的可重复使用的软件设计问题的解决方案模式体现的是程序整体的构思,所以有时候它也会出现在分析或者是概要设计阶段模式的核心思想是通过增加抽象层,把变化部分从那些不变部分里分离出来什么是软件设计模式学习设计模式的重要性学习设计模式不仅可以使我们使用好这些成功的模式,更重要的是可以使我们更加深刻地理解面向对象的设计思想,非常有利于我们更好地使用面向对象语言解决设计中的问题。模式名称(PatternName)问题(Problem):描述应该在何时使用模式。解释了设计问题和问题存在的前因后果,可能还描述模式必须满足的先决条件解决方案(Solution):描述了设计的组成成分、相互关系及各自的职责和协作方式。模式就像一个模板,可应用于多种场合,所以解决方案并不描述一个具体的设计或实现,而是提供设计问题的抽象描述和解决问题所采用的元素组合(类和对象)效果(consequences):描述模式的应用效果及使用模式应权衡的问题模式的基本要素22模式的特点模式可以解决实际问题模式可以解决具体问题,而不只是抽象的原则或策略模式是经过考验的概念模式有实际解决问题的记录,而不只是理论上的思索或推导模式中的解决方案不是显而易见的某些求解技术根据原则直接推导出问题解,但模式间接的产生问题的解—对复杂问题必须采用这种方法模式名和分类意图:设计模式是做什么的?它的基本原理和意图是什么?它解决的是什么样的特定设计问题?动机:说明一个设计问题以及如何用模式中的类、对象来解决该问题的特定情景适用性:什么情况下可以使用该设计模式?该模式可用来改进哪些不良设计?如何识别这些情况?结构:采用对象建模技术对模式中的类进行图形描述如何描述设计模式参与者:指设计模式中的类和/或对象以及它们各自的职责协作:模式的参与者如何协作以实现其职责效果:模式如何支持其目标?使用模式的效果和所需做的权衡取舍?系统结构的哪些方面可以独立改变?实现:实现模式时需了解的一些提示、技术要点及应避免的缺陷,以及是否存在某些特定于实现语言的问题代码示例:用来说明怎样实现该模式的代码片段相关模式:与这个模式紧密相关的模式有哪些?其不同之处是什么?这个模式应与哪些其他模式一起使用?描述设计模式(续)25设计模式相关术语设计模式与模式设计模式与设计原则设计模式与应用框架设计模式与软件体系结构设计模式与习惯用法26设计模式与模式模式的含义更广,可用于任意的背景中。设计模式是一种模式除设计模式外,在软件领域还有其他模式分析模式组织模式过程模式领域模式设计模式是关于面向对象设计微结构的模式这种微结构又称对象结构微结构指对象及其类之间的静态或动态关系设计模式与设计原则设计原则是面向对象设计的指导思想设计模式只是更好的遵循这些指导思想的手段之一设计模式是面向对象设计的具体技术设计模式抽象出成功设计的共性,并进行分类与标识设计模式通过描述对象、协作和责任将设计中的意图抽取出来27设计模式与应用框架应用框架是可复用的半完整基础设施应用框架可特化,以产生用户所需的应用系统。应用框架是领域分析复用的有效途径。典型的应用框架:Java平台上--GUI的Swing、持久性的JDBC、多线程类库等。分布式应用--CORBA的各种对象服务、公共设施与领域接口。工作流应用—WorkflowManagementCoalition(WfMC)的规范。每一个应用框架都有一个具体的体系结构设计模式则是抽象的,只有设计模式的例子才表达为具体代码应用框架可预先编写好,设计模式则每次使用时都需要重新实现。应用框架的设计通常在微体系结构层次采用了设计模式设计模式描述的是软件的微体系结构采用合适的设计模式可为专用应用框架提供良好的灵活性。应用框架通常特定于某一应用领域28设计模式与软件体系结构软件体系结构所研究的对象粒度更大软件体系结构可以是为单个应用设计设计模式通常是为了多个软件产品的生产线而设计某些专家也将软件体系结构看作抽象层次更高的模式29设计模式与习惯用法习惯用法所讨论的对象粒度更小习惯用法通常是与特定的程序设计语言有关设计模式通常只与特定的程序设计方法有关某些专家也将习惯用法看作抽象层次更低的模式GoV将模式划分为体系结构模式、设计模式与习惯用法3个层次30面向对象设计原则31软件的可维护性和可复用性知名软件大师RobertC.Martin认为一个可维护性较低的软件设计,通常由于如下四个原因造成:过于僵硬(Rigidity)过于脆弱(Fragility)复用率低(Immobility)黏度过高(Viscosity)RobertC.Martin面向对象设计原则32面向对象设计原则33软件的可维护性和可复用性软件工程和建模大师PeterCoad认为,一个好的系统设计应该具备如下三个性质:可扩展性(Extensibility)灵活性(Flexibility)可插入性(Pluggability)PeterCoad面向对象设计原则面向对象设计原则和设计模式也是对系统进行合理重构的指南针.重构(Refactoring)是在不改变软件现有功能的基础上,通过调整程序代码改善软件的质量、性能,使其程序的设计模式和架构更趋合理,提高软件的扩展性和维护性。34MartinFowler面向对象设计原则开-闭原则(Open-ClosedPrinciple,OCP)里氏代换原则(LiskovSubstitutionPrinciple,LSP)依赖倒置原则(DependenceInversionPrinciple,DIP)接口隔离原则(InterfaceSegregationPrinciple,ISP)单一职责原则(SingleResponsibilityPrinciple,SRP)合成复用原则(CompositeReusePrinciple,CRP)迪米特法则(LawofDemeter,LoD)35面向对象设计原则36设计原则名称设计原则简介重要性单一职责原则(SingleResponsibilityPrinciple,SRP)类的职责要单一,不能将太多的职责放在一个类中。★★★★☆开闭原则(Open-ClosedPrinciple,OCP)软件实体对扩展是开放的,但对修改是关闭的,即在不修改一个软件实体的基础上去扩展其功能。★★★★★里氏代换原则(LiskovSubstitutionPrinciple,LSP)在软件系统中,一个可以接受基类对象的地方必然可以接受一个子类对象。★★★★☆依赖倒转原则(DependencyInversionPrinciple,DIP)要针对抽象层编程,而不要针对具体类编程。★★★★★接口隔离原则(InterfaceSegregationPrinciple,ISP)使用多个专门的接口来取代一个统一的接口。★★☆☆☆合成复用