《Java高级程序设计》课件-学习情境9 建造者模式与抽象工厂模式_第1页
《Java高级程序设计》课件-学习情境9 建造者模式与抽象工厂模式_第2页
《Java高级程序设计》课件-学习情境9 建造者模式与抽象工厂模式_第3页
《Java高级程序设计》课件-学习情境9 建造者模式与抽象工厂模式_第4页
《Java高级程序设计》课件-学习情境9 建造者模式与抽象工厂模式_第5页
已阅读5页,还剩102页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

建造者设计模式一、应用场景二、建造者设计模式三、建造者设计模式的结构四、建造者设计模式的实现过程本学习情境主要内容3一、应用场景在软件开发过程中有时需要创建一个复杂的对象,这个复杂对象通常由多个子部件按一定的步骤组合而成。如游戏中的不同角色,其性别、个性、能力、脸型、体型、服装、发型等特性都有所差异;还有汽车中的方向盘、发动机、车架、轮胎等部件也多种多样;每封电子邮件的发件人、收件人、主题、内容、附件等内容也各不相同。以上所有这些产品都是由多个部件构成的,各个部件可以灵活选择,但其创建步骤都大同小异。这类产品的创建无法用工厂模式描述,只有建造者模式可以很好地描述该类产品的创建。建造者模式适用于对象结构复杂、对象构造和表示分离的情况。二、建造者设计模式1.建造者设计模式的概念建造者模式(BuilderPattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式是一种对象创建型模式。建造者模式一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。2.建造者模式的适用场合1.需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性。2.需要生成的产品对象的属性相互依赖,需要指定其生成顺序。3.对象的创建过程独立于创建该对象的类。在建造者模式中通过引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类和客户类中。4.隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。三、建造者设计模式的结构1.建造者设计模式类图2.建造者设计模式主要角色1.产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个部件。2.抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法getResult()。3.具体建造者(ConcreteBuilder):实现Builder接口,完成复杂产品的各个部件的具体创建方法。4.指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。建造者模式包含两个很重要的部分:(1)一个部分是Builder接口,这里是定义了如何构建各个部件,也就是知道每个部件功能如何实现,以及如何装配这些部件到产品中去;(2)另外一个部分是Director,Director是指导如何组合来构建产品,也就是说Director负责整体的构建算法,而且通常是分步骤地来执行。四、建造者设计模式的实现过程1.建造者设计模式时序图2.建造者设计模式的实现过程第一步,定义产品类//Product类,由多个部件组成。publicclassProduct{ privateStringpartA;//可以是任意类型

privateStringpartB; privateStringpartC; //省略setter和getter方法}由一系列部件组成,一般是一个较为复杂的对象,也就是说创建对象的过程比较复杂,一般会有比较多的代码量。第二步,定义抽象建造者类publicinterfaceBuilder{publicvoidbuildPartA();publicvoidbuildPartB();publicvoidbuildPartC();

publicProductgetResult();}在这里一般使用接口Builder。给出一个抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此接口独立于应用程序的商业逻辑。模式中直接创建产品对象的是具体建造者(ConcreteBuilder)角色。具体建造者类必须实现这个接口所要求的两种方法:一种是建造方法(buildPart),另一种是返还结果方法(getResult)。第三步,定义具体建造者类实现抽象类或接口的所有未实现的方法,具体来说一般是两项任务:组建产品;返回组建好的产品。第四步,定义指挥者类(或称导演者类)建造者模式的结构中还引入了一个指挥者类Director,该类的作用主要有两个:一方面它隔离了客户与生产过程;另一方面它负责控制产品的生成过程。指挥者类(或称导演者类)负责调用适当的建造者来组建产品,指挥者类一般不与产品类发生依赖关系,与指挥者类直接交互的是建造者类。指挥者者角色并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者角色。privateBuilderbuilder; //1构造方法的方式注入builder对象

publicDirector(Builderbuilder) { this.builder=builder; } //2set方法注入builder对象

publicvoidsetBuilder(Builderbuilder) { this.builder=builer; }需要注入builder对象。有两种注入方式。构造注入和set注入。指挥者角色是与客户端打交道的角色。指挥者将客户端创建产品的请求划分为对各个零件的建造请求,再将这些请求委派给具体建造者角色。具体建造者角色是做具体建造工作的publicProductconstruct() { builder.buildPartA(); builder.buildPartB(); builder.buildPartC(); returnbuilder.getResult(); }指挥者还有一个方法construct()建造产品,委派给具体建造者角色,即通过builder的buildPartA();方法来建造第五步,定义客户端类在客户端类的main方法中编写代码客户需要什么样的产品,交给Director,Director类注入Builder,由director的construct()方法返回产品给客户。具体建造产品的过程是construct()方法,其是通过调用concretebuilder的方法buildPartA()方法来建造产品。客户不需要知道具体的建造过程。优点:1、产品的建造和表示分离,实现了解耦。2、将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰3、增加新的具体建造者无需修改原有类库的代码,易于拓展,符合“开闭原则“。缺点:1、产品必须有共同点,限制了使用范围。2、如内部变化复杂,会有很多的建造类,难以维护。小结本学习情境讲述了建造者设计模式应用场景建造者设计模式建造者设计模式的结构建造者设计模式的实现过程建造者模式的使用实例一、任务描述二、任务分析、设计三、任务实施四、运行结果本学习情境主要内容30一、任务描述使用Java建造者设计模式编写应用程序任务需求:模拟影视作品、动漫作品、文学作品等作品的生产过程。使用Java建造者模式。二、任务分析、设计分析:影视作品、动漫作品、文学作品等作品的生产过程很复杂,一般包括人员招募、写剧本/书、筹集资金、出版发行宣传上映等过程。适合使用建造者设计模式。实现思路:按照典型建造者设计模式的实现过程,创建各个类。抽象产品类Product。具体产品类。包括:文学作品类LiteraryWorks,影视作品类FilmWorks,动漫作品类AnimationWorks建造者接口Builder。具体建造者类。包括:影视作品建造者类FilmWorksBuilder,文学作品建造者类LiteraryWorksBuilder,动漫作品建造者类AnimationWorksBuilder等。指挥者类Director。客户端类Client。其类图如图9-1所示三、任务实施第一步.定义抽象产品类publicabstractclassProduct{

publicStringproductName;//作品名称

publicStringauthor;//作者

publicdoublefundraising=0.0;//耗资

publicStringcontent;//故事情节

//省略getter和setter方法}抽象类,封装作品名称、作者、耗资及故事情节等信息封装setter和getter方法重写toString方法第二步.定义具体产品类publicclassFilmWorksextendsProduct{//影视演员列表privateArrayList<String>actorList=newArrayList<>();

//影视导演privateStringregisseur;…}FilmWorks类继承Product类,同时有自己的属性,演员列表、导演等publicclassLiteraryWorksextendsProduct{privatedoubleprice=0.0;//书籍价格…}LiteraryWorks类继承Product类,同时有自己的属性,书籍价格publicclassAnimationWorksextendsProduct{ privateStringproducedby;//动漫制作人

privateStringregisseur;//动漫导演…}AnimationWorks类继承Product类,同时有自己的属性,动漫制作人、动漫导演第三步.定义建造者角色public

interfaceBuilder{public

voidrecruiting();//人员招募public

void

writeScript();//写剧本/书public

void

raiseFunds();//筹集资金public

voidreleased();//出版,发行,宣传,上映publicProductgetProduct();//构造作品}建造者角色采用接口,其中声明了创建产品各个子部件的方法,还包含一个返回复杂产品的方法getProduct()第四步,定义各个产品的具体建造者类publicclassFilmWorksBuilderimplementsBuilder{ publicFilmWorks

filmWorks=newFilmWorks();

@Override publicProductgetProduct(){ //TODOAuto-generatedmethodstub returnfilmWorks; }}FilmWorksBuilder类实现Builder接口,其中new一个FilmWorks

的对象,重写Builder中声明的建造产品部件的方法。重写recruiting()方法。指定导演、招募演员等

/***招募人员*指定导演,招募演员*/@Overridepublic

voidrecruiting(){//TODOAuto-generatedmethodstub

filmWorks.setRegisseur("吴京");

ArrayList<String>list=new

ArrayList<>();

list.add("吴京");

list.add("余男");

list.add("倪大红");

list.add("斯科特·阿金斯");

list.add("周晓鸥");

filmWorks.setActor(list);}重写writeScript()方法/***编剧*/@Overridepublic

void

writeScript(){//TODOAuto-generatedmethodstub

filmWorks.setProductName("战狼");

filmWorks.setAuthor("董群");

filmWorks.setContent("讲述的是小人物成长为拯救国家和民族命运的孤胆英雄的传奇故事。");}重写raiseFunds()方法/***募资*/@Overridepublic

void

raiseFunds(){//TODOAuto-generatedmethodstub

System.out.println("筹资中...");}重写released()方法/***编剧、拍摄、宣传、发行、上映等需要费用*/@Overridepublic

void

released(){//TODOAuto-generatedmethodstub

filmWorks.setFundraising(10000000.00);}@OverridepublicProductgetProduct(){//TODOAuto-generatedmethodstubreturn

filmWorks;}重写getProduct()方法,返回产品同样的,定义其他的具体建造者类LiteraryWorksBuilderAnimationWorksBuilder实现Builder接口重写接口的方法第五步,

定义指挥者类public

classDirector{

publicProductconstruct(Builderbuilder){

builder.recruiting();//招募人员

builder.raiseFunds();//筹集资金

builder.writeScript();//编剧

builder.released();//出版,发行,宣传,上映return

builder.getProduct();

}}指挥者角色,通过建造者构建产品。定义方法construct(Builderbuilder)传递建造者,通过建造者建造产品,然后返回该产品第六步,

定义客户端类public

class

ClientDemo{public

static

voidmain(String[]args){

//创建指挥者对象Directordirector=newDirector();//一部电影的产生BuilderfilmWorksBuilder=new

FilmWorksBuilder();ProductfilmWorks=director.construct(filmWorksBuilder);

System.out.println(filmWorks.toString());}}首先创建指挥者对象。然后创建具体建造者对象filmWorksBuilder。再通过指挥者的construct(filmWorksBuilder)方法传递具体建造者,由建造者建造产品,并由指挥者的construct方法返回该产品。最后输出。//一部文学作品的产生LiteraryWorksBuilder

literaryWorksBuilder=new

LiteraryWorksBuilder();ProductliteraryWorks=director.construct(literaryWorksBuilder);System.out.println(literaryWorks.toString());同样的建造过程可产生文学作品同样的建造过程还可产生动漫作品四、运行结果建造者模式优点(1)在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品。(2)每一个具体建造者都相对独立。因此系统的可扩展性很好。(3)可以更加精细地控制产品的创建过程。因为建造者模式将复杂产品地创建步骤定义在指挥者类的模板方法中,而具体的创建过程定义在不同的方法中,使得创建过程更加清晰。建造者模式缺点(1)建造者模式所创建的产品需要有较多的共同点,因此建造者模式的使用有一定的限制性。(2)如果产品内部变化复杂,可能会导致需要定义较多的具体建造者类来实现这种变化,导致系统变得很庞大。小结本学习情境通过一个实例讲述了使用建造者设计模式编写应用程序的实现过程。抽象工厂模式的使用一、应用场景二、抽象工厂设计模式三、抽象工厂设计模式的结构四、抽象工厂模式的实现过程本学习情境主要内容59一、应用场景在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品。但是有时候我们需要一个工厂可以提供多个产品对象,而不是单一的产品对象。当系统所提供的工厂所需生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构中属于不同类型的具体产品时需要使用抽象工厂模式。在很多软件系统中需要更换界面主题,要求界面中的按钮、文本框、背景色等一起发生改变时,可以使用抽象工厂模式进行设计。二、抽象工厂设计模式1.抽象工厂设计模式的概念抽象工厂模式(AbstractFactoryPattern),该模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。每个生成的工厂都能按照工厂模式提供对象产品等级结构:产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构。为了更清晰地理解工厂方法模式,需要先引入两个概念:产品族:是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中。2.抽象工厂模式的适用场合一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节。系统中有多于一个的产品族,而每次只使用其中某一产品族。属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。在以下情况下可以使用抽象工厂模式:三、抽象工厂设计模式的结构1.类图2.主要角色(1)抽象工厂(AbstractFactory):提供了创建产品的接口,它包含多个创建产品的方法createProduct(),可以创建多个不同等级的产品。(2)具体工厂(ConcreteFactory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。(3)抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。(4)具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。四、抽象工厂模式的实现过程1.时序图2.抽象工厂设计模式的实现过程抽象工厂模式的结构同工厂方法模式的结构相似,不同的是其产品的种类不止一个,所以创建产品的方法也不止一个interfaceAbstractFactory{publicProductA

createProductA();publicProductB

createProductB();}第一步,创建抽象工厂AbstractFactory这里使用接口,其提供了产品族的生成方法第二步,创建具体工厂ConcreteFactory1实现了抽象工厂接口,重写产品族的生产方法第三步,创建抽象产品接口publicinterfaceProductA{ publicvoidshow();}publicinterfaceProductB{ publicvoidshow();}ProductA和ProductB是不同的产品等级结构第四步,创建具体产品publicclassProductA1implementsProductA{ publicvoidshow(){}}publicclassProductB1implementsProductB{ publicvoidshow(){}}ProductA1和ProductA

是同一个产品等级结构,即具有继承关系同样的,ProductB1和ProductB是同一个产品等级结构,即具有继承关系第五步,创建客户端类AbstractFactoryaf1,af2;ProductApa1,pa2;ProductBpb1,pb2;af1=newConcreteFactory1();af2=newConcreteFactory2();在客户端的main方法中,创建af1,af2,两个不同的具体工厂创建pa1,pa2,同一个产品等级结构创建pb1,pb2,同一个产品等级pa1,pb1是不同的产等级结构,但如果由同一个工厂生产,则是同一个产品族具体工厂生产不同种类不同等级结构的产品//具体工厂1生产产品pa1=af1.createProductA1();pb1=af1.createProductB1();System.out.println("具体工厂1生产:");pa1.show();pb1.show();具体工厂1生产pa1、pb1,即不同等级结构的产品,但,是同一个产品族。//具体工厂2生产产品pa2=af2.createProductA2();pb2=af2.createProductA2();System.out.println("具体工厂2生产::");pa2.show();pb2.show();具体工厂2生产pa2、pb2,即不同等级结构的产品,但,是同一个产品族。总结(1)抽象工厂模式包含四个角色:抽象工厂用于声明生成抽象产品的方法;具体工厂实现了抽象工厂声明的生成抽象产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中;抽象产品为每种产品声明接口,在抽象产品中定义了产品的抽象业务方法;具体产品定义具体工厂生产的具体产品对象,实现抽象产品接口中定义的业务方法。(2)抽象工厂模式的主要优点是隔离了具体类的生成,使得客户并不需要知道什么被创建,而且每次可以通过具体工厂类创建一个产品族中的多个对象,增加或者替换产品族比较方便,增加新的具体工厂和产品族很方便(3)抽象工厂模式适用情况包括:一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节;系统中有多于一个的产品族,而每次只使用其中某一产品族;属于同一个产品族的产品将在一起使用;系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。小结本学习情境讲述了抽象工厂设计模式应用场景抽象工厂设计模式的概念抽象工厂设计模式的结构抽象工厂设计模式的实现过程抽象工厂模式的使用实例一、任务描述二、任务分析、设计三、任务实施四、运行结果本学习情境主要内容88一、任务描述使用Java抽象工厂设计模式编写应用程序任务需求:一个农场既可养殖动物,又可种植植物。即农场的产品有不同的产品族、不同的产品等级结构。用抽象工厂模式设计农场类。二、任务分析、设计一个农场既可以驯养动物,如养马、养牛,还可以种植植物,种菜、种水果等。马、牛是同一个等级结构的产品,蔬菜、水果是同一个等级结构的产品,马和水果是不同等级结构产品,但由同一个农场生产,是同一个产品族。这里适合用抽象工厂模式来实现。按抽象工厂设计模式的结构,设计四个角色:(1)抽象工厂类,Farm接口(2)具体工厂类,两个农场,WuhanFarm和JiujiangFarm。(3)抽象产品类,两个接口Animal和Plant。(4)具体产品类,牛(Cattle)、马(House)、蔬菜(Vegetables)以及水果(Fruitage)最后是客户端类Client实现思路:其类图如图所示首先有一个抽象农场接口,农场1和农场2实现抽象农场接口,农场1生产牛和蔬菜,农场2生产马和水果,牛和马又实现动物接口,蔬菜和水果实现植物接口。抽象工厂中方法对应产品结构,具体工厂对应产品族。三、任务实施1.定义抽象工厂类定义农场接口,可以驯养动物和种植植物。其方法对应产品结构,即产品族。publicinterfaceFarm{publicAnimalcreateAnimal();//驯养动物

publicPlantcreatePlant();//种植植物}2.定义具体工厂类publicclassWuhanFarmimplementsFarm{

@OverridepublicAnimalcreateAnimal(){ //TODOAuto-generatedmethodstub

System.out.println("新牛出生!"); returnnewCattle();}@OverridepublicPlantcreatePlant(){ //TODOAuto-generatedmethodstub

System.out.println("蔬菜长成!");returnnewVegetables();}}WUhanFarm类实现Farm接口,重写接口的方法即武汉农场既可以养牛又可以种蔬菜。具体工厂对应产品族。这里是牛和蔬菜。publicclassJiujiangFarmimplementsFarm{@OverridepublicAnimalcreateAnimal(){ //TODOAuto-generatedmethodstub

System.out.println("新马出生!");returnnewHorse();}@OverridepublicPlantcreatePlant(){ //TODOAuto-generatedmethodstub

System.out.println("水果长成!");returnnewFruitage();}}JiujiangFarm类实现Farm接口,重写接口的方法即九江农场既可以养马又可以种水果。其产品族是马和水果。3.定义抽象产品类定义抽象产品接口,Animal和PlantpublicinterfaceAnimal{publicvoidshow();}publicinterfacePlant{publicvoidshow();}4.定义具体产品类牛(Cattle)类马(Horse

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论