面向对象方法与技术7/5/20202课程内容Part1:面向对象原理第一章面向对象的引入和发展第二章面向对象基本概念和程序设计Part2:UML第三章UML基础Part3:面向对象设计第四章面向对象设计模式第五章面向对象设计原则第4章面向对象设计模式4.1什么是设计模式在处理大量问题时,在很多不同的问题中重复出现的一种性质它使得我们可以使用一种方法来描述问题实质并用本质上相同,但细节永不会重复的方法去解决这种性质就叫模式什么是设计模式?每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的中心。这样你就能一次又一次地使用该方案而不必做重复劳动。ChristopherAlexander设计模式:起源起源ChristopherAlexander当代著名建筑大师加州大学伯克利分校建筑学教授、环境结构研究所所长、美国艺术与科学院院士在建筑、室内、计算机、家具设计甚至哲学方面都卓有建树著作:《APatternLanguage》、《TheTimelessWayofBuilding》6Gof(GangOfFour,“四人帮”)ErichGamma,RichardHelm,RalphJohnson,JohnVlissides《DesignPatterns:ElementsofReusableObject-OrientedSoftware》(1995,AddisonWeslyLongman.Inc)该书确立了设计模式这个术语,创导了一种新的面向对象设计思潮7设计模式:起源8设计模式什么叫模式?“每一个模式描述了在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样,你就能一次又一次地使用该解决方案而不必重复劳动”尽管软件技术发展非常快,但是仍然有非常多的设计模式可以让我们套用设计模式可以帮助人们简便地复用以前成功的设计方案,提高工作效率9好的模式它可以解决问题所提出解决方案是正确的,而且不是很明显的必须是涉及软件系统深层的结构的东西,不能仅是对已有的模块的描述它必须满足人的审美,简洁美观设计模式的思想根源基本原则的宏观运用,本质上是没有任何模式的发现模式的人永远是大师,而死守模式的人,最多只能是一个工匠设计模式基本要素模式名称(patternname)问题(problem)解决方案(solution)效果(consequences)(gof提出的23个)12创建型结构型行为型类FactoryMethodAdapter(类)InterpreterTemplateMethod对象AbstractFactoryBuilderPrototypeSingletonAdapter(对象)BridgeCompositeDecoratorFacadeFlyweightProxyChainofResponsibilityCommandIteratorMediatorMementoObserverStateStrategyVisitor4.2模式分类设计模式的分类创建模式分类Factory(工厂模式)提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。Prototype(原型模式)用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。Builder将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。Singleton(单态模式)保证一个类只有一个实例,并提供一个访问它的全局访问点。结构模式分类Facade为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。Proxy为其他对象提供一个代理以控制对这个对象的访问。Adapter将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。Composite将对象组合成树形结构以表示“部分-整体”的层次结构。它使得客户对单个对象和复合对象的使用具有一致性。就是将类用树形结构组合成一个单位.你向别人介绍你是某单位,你是单位中的一个元素,别人和你做买卖,相当于和单位做买卖。结构模式分类–续DecoratorDecorator是个油漆工,给你的东东的外表刷上美丽的颜色。动态地给一个对象添加一些额外的职责。就扩展功能而言,它比生成子类方式更为灵活。Bridge将抽象部分与它的实现部分分离,使它们都可以独立地变化。将牛郎织女分开(本应在一起,分开他们,形成两个接口),在他们之间搭建一个桥(动态的结合)Flyweight运用共享技术有效地支持大量细粒度的对象行为模式分类Template定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。Memento在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到保存的状态。Observer定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。ChainofResponsibility为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。各司其职的类串成一串,好象击鼓传花,当然如果自己能完成,就不要推委给下一个.行为模式-续Command将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。State允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它所属的类。状态是编程中经常碰到的实例,将状态对象化,设立状态变换器,便可在状态中轻松切换。Strategy定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法的变化可独立于使用它的客户。Mediator用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。Mediator很象十字路口的红绿灯,每个车辆只需和红绿灯交互就可以.行为模式-续Interpreter给定一个语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子。Visitor访问者在进行访问时,完成一系列实质性操作,而且还可以扩展.Iterator这个模式已经被整合入Java的Collection.在大多数场合下无需自己制造一个Iterator,只要将对象装入Collection中,直接使用Iterator进行对象遍历。4.3创建性模式简单工厂工厂方法抽象工厂单例模式创建型模式想吃苹果!?创建型模式通常获取苹果的两种方式自己种苹果树去超市买4.3.1简单工厂模式动机只要说出水果的名字就能得到想要的水果。AppleOrangeBanana简单工厂模式当看到“new”,就会想到“具体”当遇到一群相关的具体类时,通常见到下面的代码PizzaorderPizza(Stringtype){Pizzapizza;if(type.equals(“cheese”)){pizza=newCheeasePizza();}elseif(type.equals(“greek”)){pizza=newGreekPizza();}elseif(type.equals(“pepperoni”)){pizza=newPepperoniPizza();}…}如果增加更多的产品类型怎么办?另一个例子开始封装创建对象的代码建立一个简单工厂当需要pizza时,就叫工厂做一个PublicclassSimplePizzaFactory{publicPizzacreatePizza(Stringtype){Pizzapizza=null;if(type.equals(“cheese”)){pizza=newCheeasePizza();}elseif(type.equals(“greek”)){pizza=newGreekPizza();}elseif(type.equals(“pepperoni”)){pizza=newPepperoniPizza();}returnpizza;}}26定义简单工厂+orderPizza()PizzaStore+createPizza()SimplePizzaFactory+prepare()+bake()+cut()+box()PizzaCheesePizzaVeggiePizzaClamPizzaPepperoniPizza27fruitgardenerpublicclassFruitGardener{publicstaticFruitIFfactory(Stringwhich)throwsBadFruitException{if(which.equalsIgnoreCase(apple)){returnnewApple();}elseif(which.equalsIgnoreCase(strawberry)){returnnewStrawberry();}elseif(which.equalsIgnoreCase(grape)){returnnewGrape();}else{thrownewBadFruitException(Badfruitrequest);}}}使用简单工厂个的例子在使用时,只须调用FruitGardener的factory()方法即可FruitGardenergardener=newFruitGardener();gardener.factory(grape);gardener.factory(apple);gardener.factory(strawberry);简单工厂的UML表示法参与者Factory:工厂角色Product:抽象产品角色ConcreteProduct:具体产品角色简单工厂的优缺点优点:实现了责任分割利用判断逻辑,决定实例化哪一个产品类客户端可以免除直接创建产品类对象的责任,仅仅使用该产品缺点:没有完全做到“开-闭”一旦增加新的产品,需要修改工厂的代码但是客户代码不需要修改“我不入地狱谁入地狱”应用情景工厂类负责创建的对象比较少客户只传入参数,对于何始创建对象(逻辑)不关心314.3.2FactoryMethod(工厂方法)模式例子:“去快餐厅吃饭”3233voidBuyFood(string餐馆,string食品){if(餐馆==KFC){if(食品==Chicken)hamburger=newKFCChickenHamburger;elseif(food==Fish)hamburger=newKFCFishHamburger;}elseif(restaurant==McDonald){if(food==Chicken)hamburger=newMcDonaldChickenHamburger;elseif(food==Fish)hamburger=newMcDonaldFishHamburger;}}FactoryMethod(工厂方法)模式增加一种新的食物呢?34FactoryMethod(工厂方法)模式传统设计的缺点依赖具体35voidBuyFood(string餐馆,string食品){if(餐馆==KFC){if(食品==Chicken)hamburger=newKFCChickenHamburger;elseif(food==Fish)hamburger=newKFCFishHamburger;}...设计原则:依赖倒置原则依赖具体的缺点36FactoryMethod(工厂方法)模式简单工厂的问题所有具体产品对象的创建都放在一个类中,一旦