版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、模式:模式,即aern。事实上确实是解决某一类问题的方法论。把解决某类问题的方法总结归纳到理论高度,那确实是模式。lexander给出的经典定义是:每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核心。通过这种方式,你能够许多次地使用那些已有的解决方案,无需再重复相同的工作。模式有不同的领域,建筑领域有建筑模式,软件设计领域也有设计模式。当一个领域逐渐成熟的时候,自然会出现专门多模式。设计模式和面向对象的设计模式:设计模式(Dsign patter)是一套被反复使用、多数人知晓的、通过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人
2、理解、保证代码可靠性。设计模式最初来源于建筑学。GOF(“四人帮”,指Gamm,el, Johnson &Vlissies,Addison-Wesley四人)的设计模式(99年出版)是第一次将设计模式提升到理论高度,并将之规范化,本系列文章要紧确实是讲解这23种经典的设计模式。面向对象设计的模式,顾名思义,确实是在面向对象分析与设计中使用的设计模式,GOF23种设计模式同时也是面向对象的设计模式,本文不做区分。良好的设计模式运用能够实现软件设计的“高内聚、低耦合”,提高软件的复用性和可扩展性。框架:框架,即Framework。事实上确实是某种应用的半成品,确实是一组组件,供你选用完成你自己的系
3、统。简单讲确实是使用不人搭好的舞台,你来做表演。而且,框架一般是成熟的,不断升级的软件。框架一般处在低层应用平台(如JEE)和高层业务逻辑之间的中间层。架构:架构(rchitctre)是一系列相关的抽象模式,用于指导大型软件系统各个方面的设计。架构是一个系统的草图。架构描述的对象是直接构成系统的抽象组件。各个组件之间的连接则明确和相对细致地描述组件之间的通讯。在实现时期,这些抽象组件被细化为实际的组件,比如具体某个类或者对象。在面向对象领域中,组件之间的连接通常用接口来实现。一些刚入门的程序员经常会混淆“框架”和“架构”这两个名词,那个地点做了一下解释。我们什么缘故要使用设计模式呢?有人可能会
4、讲为了设计出高内聚低耦合的软件。高内聚低耦合的软件实际上也确实是本文所讲的具有可维护性和可复用性的软件。这篇文章要紧讲解两方面内容,这两方面是软件设计中专门重要,也是专门关键的内容,希望大伙儿认真考虑并深刻理解。第一部分确实是关于软件的可维护性和可复用性的相关内容,第二部分确实是在第一部分的基础上逐条讲解面向对象软件设计的差不多原则,本文内容差不多上些专门理论性的东西,这些理论是软件设计的基础。凡是有理论的地点,就有如何恰当的将理论应用到实践中去的问题,设计模式是关于学习O设计原则的具体指导,也确实是讲设计模式确实是将这些理论应用到实践的一种成熟的方式。软件的可维护性和可复用性首先来上一段大师
5、所讲的话,专门经典。“通常认为,一个易于维护的系统,确实是复用率较高的系统;而一个复用率较高的系统,确实是一个易于维护的系统。然而实际上,可维护性和可复用性是两个独立的目标,就像两只奔驰的兔子一样,并不总是方向一致的。关于面向对象的软件系统设计来讲,在支持可维护性(Maitaiabit)的同时,提高系统的可复用性(eueabilty)是一个核心的问题。”-Java与模式阎宏博士 软件系统的可维护性:软件维护确实是软件的再生。一个好的软件设计,必须能够同意新的设计要求以比较容易和平稳的方式加入到已有的系统中去,从而使那个系统能够不断的的焕发出活力。一个可维护性较好的系统,应当同意维护工作能够以容
6、易、准确、安全和经济的形式进行。【导致可维护性较低的缘故】1、过于僵硬:在系统中加入一个新的功能,不管大小都专门难,不仅意味着建筑一个独立的新的模块,而且因为那个新功能会波及专门多其他模块,最后成跨越几个模块的改动。2、过于脆弱:与软件的过于僵硬同时存在,是软件系统在修改已有代码时过于脆弱。对一个地点的修改,往往会导致看上去没有什么关系的另外一个地点发生故障。3、复用率低:所谓复用,确实是指一个软件的组成部分,能够在同一个项目的不同地点甚至另一个项目中重复使用。复用率低,指当一段代码,函数,模块的功能能够在新的模块或新的系统使用,然而已有代码依靠于其他专门多东西,专门难分开。4、黏度过高:一个
7、改动能够保存原始设计意图和原始设计框架的方式进行,也能够以破坏原始意图和框架进行。第一种方法对系统的以后有利,第二种方法是权宜之计,能够解决短期的问题,然而会牺牲中长期的利益。假如一个系统中使用第二种方法比使用第一种方法容易,那么确实是黏度过高。【设计的目标】、可扩展性:新的性能能够专门容易地加入到系统中去,确实是可扩展性。这确实是系统“过于僵硬”的属性的方面。2、灵活性:能够同意代码修改平稳地发生,而可不能波及到专门多其他的模块,这确实是灵活性。灵活性事实上确实是“过于脆弱”的属性的方面。3、可插入性:能够专门容易地将一个类抽出去,同时将另外一个有同样接口的类加入进来,这确实是可插入性。事实
8、上,这确实是“黏度过高”的方面。 软件系统的可复用性:【软件复用的好处】、较高的生产效率;2、较高的软件质量;3、恰当使用复用能够改善系统的可维护性。【传统的复用形式】1、代码的剪贴复用;2、算法的复用;3、数据结构的复用。【面向对象设计的复用】在面向对象语言中,数据的抽象化,继承,封装和多态性使得一个系统能够在更高层次上提供可复用性。数据的抽象化和继承关系使得概念和定义能够复用;多态性使得实现和应用得到复用;而抽象化和封装能够保持和促进系统的可维护性,复用的重点转移到含有宏观商业逻辑的抽象层次上。在面向对象的设计里面,可维护性复用是以设计原则和设计模式为基础的。提高系统可维护性和可复用性的设
9、计原则、“开闭”原则(Ope-Cls Prinle,或者OC);一个软件实体应该对扩展开放,对修改关闭;在设计一个模块的时候,应当使那个模块能够在不被修改的前提下被扩展。换言之,应当能够在不必修改源代码的情况下改变那个模块的行为。那个原则实际上是对“对可变性的封闭原则“:找到一个系统的可变因素,将之封装起来。那个原则意昧着两点:1) 一个可变性不应当散落在代码的专门多角落里,而应当被封装到一个对象里面。同一种可变性的不同表象意昧着同一个继承等级结构中的具体子类。继承就当被看作是封装变化的方法,而不应当被认为是从一般的对象生成专门对象的方法。) 一种可变性不应当与另一种可变性混合在一起。(所有类
10、图的继承结构一般可不能超过两层,不然就意昧着将两种不同的可变性混合在了一起。)那个原则是总的原则,其它几条是那个原则的手段和工具。2、里氏替代原则(Lsv stitution Principle,或者S);假如关于每一个类型为T1的对象o1,都有类型为T的对象o,使得以1定义的所有程序P在所有的对象o都代换成2时,程序P的行为没有变化,那么类型T2是类型T1的子类型。换言之,一个软件实体假如使用的是一个基类的话,那么一定适用于其子类,而且它全然不能察觉出基类对象和子类对象的区不。反过来代换不成立。3、依靠倒转原则(DeendencyInersio Pinciple,或者IP);要依靠于抽象,不
11、要依靠于具体。开闭原则是目标,而达到这一目标的手段是依靠倒转原则。抽象层次包含的是应用系统的商务逻辑和宏观的、对整个系统来讲重要的战略性决定,是必定性的体现,那么抽象层次就应当是较为稳定的,应当是复用的重点;也应当是维护的重点;而具体层次则含有一些次要的与实现有关的算法和逻辑,以及战术性的决定,带有相当大的偶然性选择。具体层次的代码是会经常有变动的,不能幸免出现错误。4、接口隔离原则(nterfce Segregtion Princie,或者ISP);使用多个专门的接口比使用单一的总接口要好。换言之,从一个客户类的角度讲:一个类对另一个类的依靠性应当是建立在最小的接口上的。接口隔离原则与迪米特
12、法则(下面讲到)差不多上对一个软件实体与其他的软件实体的通信限制。迪米特原则要求尽可能地限制通信的宽度和深度,接品隔离原则要求通信的宽度尽可能地窄。如此做的结果使一个软件系统在功能扩展过程当中,可不能将修改的压力传递到其他对象。一个接口相当于剧本中的一种角色,而此角色在一个舞台上由哪一个演员来演则相当于接口的实现。因此,一个接口应当简单地代表一个角色,而不是多个角色。假如系统涉及到多个角色的话,那么每一个角色都应当由一个特定的接口代表。5、组合/聚合复用原则(omposionggregation Picipl,或者ARP);组合/聚合原则确实是在一个新的对象里面使用一些已有的对象,使之成为新对
13、象的一部分;新的对象通过向这些对象的委派达到得复用已有功能的目的。要尽量使用组合/聚合,尽量不要使用继承。6、迪米特法则(Law eter,或者L);一个软件实体应当尽可能少的与其他实体发生相互作用。模块之间的交互要少。如此做的结果是当系统的功能需要扩展时,会相对更容易地做到对修改的关闭。一个对象应当对其他对象有尽可能少的了解。7、单一职责原则(SingleRepoibility riciple,或者SP)在设计中为每种职责设计一个类,彼此保持正交,互不干涉。那个原则比较容易理解,那个地点不在多讲。小结当我们掌握了C的语法,当我们了解了面向对象的封装、继承、多态等特性,当我们能够用各种框架与技
14、术构建桌面以及Web应用时,这并不意味着我们能够写出面向对象的程序,不意味着我们能够专门好的实现代码复用,弹性维护,不意味着我们能够实现在维护、扩展基础上的代码复用。使用面向对象语言开发的程序不一定是面向对象的,使用面向过程的语言开发的程序也不一定不是面向对象的。要想开发出一个具有可维护性和可复用性的软件系统,那是需要优秀的设计和长时刻的运行才能完成的,事实上我们能够观看一下,任何一个优秀的软件产品差不多上通过长时刻的设计,运行,维护,修改等最后才成为成功的产品,版本上也在不断的更新。衡量一个软件开发者是不是一个好的软件开发者,不是看他是否实现了软件的必要功能,而是要看你的软件在满足功能需求的
15、情况下是否做到了复用性和可扩展性,这关于一个大型系统尤其重要。我们不要静止的看待一个软件,而一定要把软件过程放在时刻轴上来观看与设计它,只有放在时刻轴上经得住考验的软件系统才是成功的。软件的复用性和可扩展性关于大型系统是必要的,我们在设计自己的软件系统时,甚至在编写代码时更需要考虑一下如此做是否遵循了系统设计的原则,是否有利于系统的可维护性和可复用性,是否达到了常讲的“高内聚低耦合”呢?设计模式正是解决这一问题的王道。从下文开始我们将结合实例关于GoF23种设计模式进行一一讲解。现在我们正式进入GF2种设计模式中的创建型模式的讲解中来,创建型模式要紧解决对象如何创建的问题,提倡创建对象的责任和
16、使用对象的责任分离,以达到更好对创建对象的操纵的目的,创建型模式要紧包括抽象工厂(Abstractacty),建筑者(ilde),工厂方法(FctryMetho),原型(Potote),单子(Siglto)。这篇文章要紧分为两大部分内容,在第一部分中我将介绍抽象工厂模式的原型,包括抽象工厂的意图,能够解决的问题,原型代码和UL等,再结合一个生活中的小例子进行原型的讲明。第二部分我会结合实际项目来讲述一下抽象工厂模式是如何应用的。最后我会对抽象工厂模式进行一个小结。工厂模式的几种形态工厂模式专门负责将大量有共同接口的类实例化。工厂模式能够动态决定将哪一个类实例化,不必事先明白每次要实例化哪一个类
17、。工厂模式有以下几种形态:简单工厂(Simpl actry)模式:又称静态工厂方法模式(tic FactoryMethod ater)。要紧是工厂中提供一个静态的方法用来依照不同的参数创建不同的抽象产品的具体实例,一般在IC中应用比较多,例如通过反射机制和简单工厂模式能够解决依靠注入的问题。简单工厂模式不属于GF23种设计模式,那个地点也就不再作过多的分析。感兴趣的园友能够找找相关资料。工厂方法(actory Metod)模式:又称多态性工厂(PolymorpicFatory)模式或虚拟构造子(rtua strctr)模式。那个模式属于GoF23种设计模式之一,在后面的文章中会做详细的介绍。抽
18、象工厂(Abstract Fctory)模式:又称工具箱(K或Tolkit)模式。这是本文的重点。抽象工厂模式的原型描述:假设一个子系统需要一些产品对象,而这些产品对象又属于一个以上的产品等级结构。那么为了将消费这些产品的责任和创建这些产品对象的责任分割开来,能够引进抽象工厂模式。如此的话,消费产品的一方不需要直接参与产品的创建工作,而只需要向一个公用的工厂接口请求所需要的产品。意图:抽象工厂模式能够向客户端(Clien指代码模式的使用者,后文类同)提供一个接口,使得客户端在不必指定产品的具体类型的情况下,创建多个产品族(Prodct Famiy指位于不同产品等级中,功能相关联的产品的集合)中
19、的产品对象。模式原型ML:抽象工厂涉及到以下角色:抽象工厂(AstractFacto )角色:声明一个操作集合的接口以创建抽象产品族。具体工厂(oncreFatory)角色:实现创建具体产品族的抽象工厂的实现。抽象产品(bsrtPoduc )角色:声明一个产品的接口。具体产品(Prodt)角色:定义了一个被具体工厂创建的产品对象,实现了抽象工厂接口。客户端(Cent)角色:使用抽象工厂和抽象产品的类。 模式原型代码:usin Sm;aesace DsgnPens.Cetonal / 测试程序 lass inApp puic taticvoi M() / 抽象工厂1 AbstrctFctoy f
20、atry1 = new ConrtFatory(); Clint c1 nw Cien(acory); c1.Run(); / 抽象工厂2 Astrattorfatry=new Concretetoy2(); Clenc = nClient(facto2); .un(); /等候用户输入 ConsoleRead(); / 抽象工厂 abstract class AbstactFcor blicbsractAbtrctrutA CreatePoductA(); publicsract AbstactProuct CreateProutB(); / 具体工厂1 clas ConreeFactory
21、1 : AbstacFactoy bicoerrde Abractroduct eterouA() retur new PoducA1(); puliorri AbsrctProdu CreatePrductB() reu new ProductB(); /具体工厂 class ConcteFry2 : Asractctory pblic overridebstratProdtA CrtePrductA() urn ew PrtA2(); pblc overide AtrctPrdctB CetPrdutB() etur newProducB(); /抽象产品,产品族中一个成员 astract
22、clssAbstactPduct / 抽象产品,产品族中一个成员 bstct clssbstractProdutB pbabstrct void Inerac(bstraPota); / 具体产品A1 as ProductA: AbtrcProducA / 具体产品B1 lassProductB1 : AbsractProductB public oerievoid Interact(AbsctPotA a) Conle.WritLine(this.GetTye().Nae + intrct wit + aGetTye()Nae); / 具体产品A2 ass ProdcA2 : Abstrac
23、Product / 具体产品B2 lssProuctB : bstactroduct publicovrride void Iterat(AstractProductAa) Console.WrieLine(sGetType().ame inerat wih + a.GtType()Name); / 客户端,使用环境 clas Clien preAbtrProdutA Absactrodct; pive AstactProct AbstractrouctB; / 构造,注意通过构造传入抽象工厂 publi lient(racactoy fctory) AbtrcProducB= fctory.
24、reterouctB(); AbstctProduct factor.eatePodctA(); pulc oid Rn() AbsrctProducteac(bstractProucA); /抽象工厂模式原型代码ingysem;namesaceesnPatternsCationl/测试程序asMainApblcstticvoidin()/抽象工厂1stactFactoryfatry=ewoncetactory1();lientc1newCient(facty1);c.n();/抽象工厂2btractFatryfactor=ewConcetFctr2();Clin2nwClent(fctory
25、);c.Rn();/等候用户输入Cosle.a();/抽象工厂btratclasAbsactactorypublicabsactAstcProducACreatePoctA();pblicbsracAstctPoduBCateProcB();/具体工厂1lssConcreteFactor1:bstrcactorypubioverdbsractdutACreteProuc()returnneProutA();pubicoverrdeAbractPouctBCreaterodB()turnroducB();/具体工厂2lsCncreteactoy2:AsactFactorublicveriebst
26、rcProuctACrteProductA()reurwroductA2();pubicoverrdAbstratduBCreateProduct()reurnnPouctB();/抽象产品A,产品族中一个成员abstracclsAbsatProduct抽象产品B,产品族中一个成员abtractcasAtrctPoductBublcabstracidIntact(AstatProuctAa);/具体产品Aclassoduct:AbstractPoductA/具体产品1lassProdut1:bstractProducBblicoerdevodIerac(AbstrctroductAa)Cnol
27、.WrtLne(thsGetTye().Nam+interactswit+a.GetType()Nam);/具体产品A2lassProdt2:AstctPodct/具体产品2lassPduct2:AstacPodtpbicverrdvoidnterac(AbsrctPrductAa)Conle.WriteLne(thi.etTe().Nae+intrctsitha.GeType()Name);/客户端,使用环境classetprvatAbtrctodutAAsrtdctA;pivatebsrctroductBAstractProducB;/构造,注意通过构造传入抽象工厂pubicClient(
28、AbstractForyfactor)AbstractProucB=factoryeateProdctB();AbtctroduA=acory.CreatrdctA();pbicvoidun()bsractPodut.Inerac(AbtrctPrducA);输出结果为:rouctB nteractswi PrctArodctB2inteawth rctA2 生活中的实例:那个生活中的实例代码演示了一个电脑游戏,在游戏中建立不同的动物世界会使用不同的工厂。尽管创建动物的大陆工厂是不同的,然而动物之间的相互关系保持不变。 eaworld codeusng Abstrac Fctoy i C#us
29、ingSyem;namspae Designterns.CratialAaFatry.Ralord clasManpp pblc statc voidMain() / 创建非洲大陆 Cntinentcr aric = nw AricaFctory(); AiaWordwold = new AnmalWrld(afria); orl.RnFoodCan(); / 创建美洲大陆 otinentFacory amica nw Amricactory(); word=newnimalWorld(aerica); world.RunFooChin(); / 等待用户输入 CosoleRady(); /抽
30、象工厂 bract clss ConinetFactory / 创建食草动物 publicastact Hivoe reteHerbivore(); / 创建食肉动物 ublc abract Cariore CeateCarivore(); / 具体工厂1 cass fricactory: CntinentFactory pulicor rivoe CateHerbivore() / 返回牛羚 eurn nw Wldebe(); pblverrde Carnvore CrateCanvor() / 返回狮子 return new Lion(); / 具体工厂 clAmercFacory :nn
31、entFacr pulicoeideerbiore reaeeriore() / 返回野牛 returnn Bison(); ublic oerie Caivor CeateCavre() / 返回狼 etnnwWolf(); / 抽象产品A abstclass Herbivore /抽象产品B asractclasarivore /交互关系,食肉动物能够吃掉食草动物 pblic abracti Et(Herbivoe h); /具体产品1 class Weest : Heriv / 具体产品B1clas Lin:Carnivore publcverde void at(Hrivr h) /
32、吃掉牛羚 Consl.Writeine(this.Gete().Nae ts + hGeyp().Nae); /具体产品A2 class Bison :Hebioe / 具体产品B2 clss Wf: arivre puli oerde voiEt(Herbvre) /吃掉野牛 onlteLine(ths.GetType().ae + ats + h.eT().Name); /客户端 clas Aimalord prveHebior _herivore; rvatearnivoe _crnivore; / 通过构造器传入具体工厂 uic AnimlWol(Cntinentator facto)
33、 crniore= facory.retCrivor(); _rivoe = fatoryCrateHrbivo(); ulic oid RunoodCain() _carnivor.Eat(_hrbre); Ral world ousn bstrct acory in CusinSyste;nmesaceDesgnPrs.CationalArtFactry.lWordclassMainAblcstticvidMai()/创建非洲大陆CntientFactorafric=nricFactoy();AnimaWodwrld=nwAnmWold(afica);world.RunFodhai();/
34、创建美洲大陆ContinenFctoryamrcnewricFactry();word=nenialWorld(america);world.nFoodChan();/等待用户输入Console.e();/抽象工厂bsctassCoinentator/创建食草动物publcabstratHebivoCHerivre();/创建食肉动物publicsractCrnvoreCraterivore();/具体工厂1lasAfriaFacory:CotinentFatrypublicoverideHerbioreCateHrbivore()/返回牛羚eturnnewWildeest();puliovr
35、rdeCarivoreCreateCrniore()/返回狮子rturnnwLion();/具体工厂2clssAmeicactory:otinentatrypublicverrideerbivoreeateHebvr()/返回野牛rtnewion();pulicverrideCarniorreateCanvore()/返回狼ernnewWolf();抽象产品AabtratclssHebivore/抽象产品BstratlassCrnvore/交互关系,食肉动物能够吃掉食草动物labtacvoEat(Herbivoreh);/具体产品A1cssWildeeest:Herivo/具体产品B1clas
36、Lion:CaivrpublcoverdevoidEat(Hrbivore)/吃掉牛羚Console.WriteLie(tis.Getyp()Naets+h.GtTpe().Name);/具体产品2clasion:ero/具体产品B2clWol:rnvopblicvrridevoida(Hebivoreh)/吃掉野牛CnsleWieLine(ti.GeTye().Name+ets+hGeType().Name);/客户端lsAnimlWordprivteerbivre_herbivore;prvteCarnivorecarnivore;通过构造器传入具体工厂ublinmaWl(Cntineta
37、trfacry)_carnivore=fctory.Crtearnvre();_erbior=factryCrateHrbore();publicvuoodhain()canivoe.Eat(hebivre);输出的结果为:Lon t ildebeestWlf etsBison什么情况下使用抽象工厂:文献【OF9】指出,在以下情况下应当考虑使用抽象工厂模式:1.一个系统不应当依靠于产品类实例如何被创建、组合和表达的细节,这关于所有形态的工厂模式差不多上重要的。2、那个系统的产品有多于一个产品族,而系统只消费其中某一个族的产品(上面这一条叫做抽象工厂模式的原始用意。)3、同属于同一个产品族的产品
38、是在一起使用的,这一约束必须在系统的设计中体现出来。4、系统提供一个产品类的库,所有的产品以同样的接口实现,从而使客户端不依靠于实现。实际项目举例现在需要创建分属于不同操作系统的视窗构件。比如命令按钮(Buttn)与文本框(ext)等差不多上视窗构件,在NIX系统的视窗环境和Wnds操作系统的视窗环境中,这两个构件有不同的本地体现,它们的细节也有所不同。在每一个操作系统中,都有一个视窗构件组成构件家族。在那个地点确实是Button和Text组成的产品族。而每一个视窗构件都构成自己的等级结构,由一个抽象角色给出抽象的功能描述,而由具体子类给出不同操作系统的具体实现,如下图所示。能够发觉在上面的产
39、品类图中,有两个产品的等级结构,分不是Buttn等级结构和ext等级结构、同时有两个产品族,也确实是IX产品族和Widws产品族。UNIX产品族由nixtn和UixTt产品组成;而Window产品族由iButton和WnTx产品构成。系统对产品对象的创建需求由一个工厂的等级结构满足,其中有两个具体工厂角色,即UnFctory和WinFactry。UiFactory对象负责创建Unix产品族中的产品,而Wiactory对象负责创建Windos产品族中的产品。这确实是抽象工厂模式的应用,抽象工厂模式的解决方案如下图所示。显然,一个系统只能够在某一个操作系统的视窗环境下运行,而不能够同时在不同的操作
40、系统上运行。因此,系统实际上只能消费属于同一个产品族的产品。那个案例实际上也正是抽象工厂模式的起源。实现的代码如下。Projeccode using bstract actory i C#/抽象工厂起源案例usystem;namespceDesigatrnCreatonal.AbstrctFacty.ProjectclassMaiAppublicsttivoMain()/创建Unix使用环境OFactoyuixnewnxFacry();Clientcnt=newClen(unix);clent.Run();/创建Windows使用环境OSactrywindows=nwWnFactory();c
41、lintnewClie(windws);clntRn();/等待用户输入onole.Reade();/抽象工厂astractclassOSFctor/创建按钮构件publcabstrctButonCreateButo();/创建文本框构件puiastractetCreateText();/具体工厂1classUFactor:OSFactorypubicverdutoreteButton()/返回nix下的utonrurnnwUixButo();pulicveridextCreateext()/返回Unix下的TexteturnewnixText();/具体工厂lasWFtory:OSFactr
42、yublicovrideButtonCeaeBtton()/返回Winows下的ttorernnewWinButton();puicoerriextCeteText()/返回Windws下的TeturnewWinTe();/抽象产品Aastactclssuttn/抽象产品atrctcassText/交互关系publictractviInteract(Bttob);/具体产品AcaUnixutton:Button/具体产品1classUniTxt:Tetpublcoverridevoidteac(utonb)Cno.WrteLine(this.GetType()Nam+nteractwihb.G
43、tye()Nam);/具体产品AclssWinButon:Buon/具体产品B2clasinText:Txpublcoverrevointeract(Butonb)Consol.Writeine(this.Gtype().Nm+itractwith+b.GeType().Name);/客户端cssClintrivButton_button;pieTextex;/通过构造器传入具体工厂ublcClint(OFaryfactoy)button=factor.CreateButton();_text=factoyCreTx();publicvoRun()text.nterac(_utn);输出结果为
44、:roetcode uing btract Factor in C#/抽象工厂起源案例using System;napac DesigPatrns.Creational.bsratFatry.Pojt clasnpp public staicvidain() /创建Unix使用环境 OSacryunix= new UnixFactoy(); Cliet cint= new lent(uni); clntRun(); / 创建Wndos使用环境 OSFctory winws = nwWinFactor(); cliet= nw Ce(winds); cet.Run(); / 等待用户输入 Cos
45、oeRaKe(); / 抽象工厂 aractclass OSFactoy / 创建按钮构件 pulicabstract Butto reteButton(); / 创建文本框构件 public bstractex CreeTxt(); / 具体工厂 cas ixFactry: SFactory ulicoverrideuton CeteButt() / 返回Unix下的Butto rtuneniButton(); pbicoverride ext CeteTex() / 返回Uix下的Tt reurn ew UnixText(); /具体工厂2 as WiFcory: OSFacr pulic
46、override utn reteutton() 返回Wws下的Buon rurn wWnutton(); publicovrde ext reteTet() / 返回n下的ex reur ew inText(); 抽象产品A abstractclass utton /抽象产品B abstact clas Text / 交互关系 ubic astrat vod nterct(uto b); / 具体产品A1 class niButon: Btton /具体产品B1 class xTet : Tex ublc ovede vd Itert(But ) Console.WriteLine(this
47、.GetTye().Nme + terctwit + b.Getype()Ne); / 具体产品A classWinButton: Button 具体产品B clss WinTet: Text public override voidnteact(uton ) Conol.WriLine(thi.GetTye().Name + ierc with + .GtType().Name); / 客户端 clss Clit iat uton _utton; piate Tex text; / 通过构造器传入具体工厂 pui Client(SFctryfactoy) _bton actoryCrateB
48、ttn(); _tex= fatory.rateTt(); ubic voiRn() _tex.Itet(_buton); UnixTt intect wit nixBttnWinText iterctwith inuton小结抽象工厂模式是一个在实际项目中应用比较多的设计模式之一,抽象工厂模式面对的问题是多个产品等级结构的系统设计,运用抽象工厂模式的关键在于假如把创建产品的职责交给工厂去完成,希望大伙儿在把握住工厂模式原型的基础上尽量的考虑到应用,形成一种思维上的定势。这一篇我将向大伙儿讲解建筑者(Builder)模式。在上一篇文章中我们要紧学习了抽象工厂(Abstact Fatory)模式
49、,抽象工厂模式要紧解决对不同等级结构的产品的创建工作,要紧关注的是创建哪一批产品的问题,而本文所讲的建筑者模式要紧是解决关于一个产品如何分部创建的问题,这是关于建筑者模式的最初描述。同样,这篇文章要紧分为两大部分来讲解,第一部分我会对建筑者模式的原型进行详细的讲明,第二部分会对建筑者模式如何解决具体问题进行探讨。建筑者模式的原型描述:在软件系统中,有时候面临一个复杂对象的创建工作,其通常由各个部分的子对象用一定算法构成;由于需求的变化,那个复杂对象的各个部分经常面临着剧烈的变化,然而将它们组合到一起的算法却相对稳定。建筑者模式是对对象的创建模式。建筑者模式能够将一个产品的内部表象与产品的生成过
50、程分隔开来,从而能够使一个建筑过程生成具有不同的内部表象的产品对象。建筑者模式利用一个导演者对象和具体建筑者对象一个一个地建筑出所有的零件,从而建筑出完整的产品对象。建筑者模式将产品的结构和产品的零件建筑过程对客户端隐藏起来,把对建筑过程进行指挥的责任和具体建筑零件的责任分隔开来,达到责任划分和封装的目的。 意图:将一个复杂对象的构建与其表示相分离,使得同样的构建过程能够创建不同的表示。模式原型M:建筑者模式涉及到以下角色:、抽象建筑者(uilder)角色:给出一个抽象接口,以规范产品对象的各个组成成分的建筑。此接口中一般至少规定两个方法,一个是创建部分的方法,例如BildrPart,另一个是
51、返回结果的方法,例如GetProduc,以约束具体建筑者实现。2、具体建筑者(Coneteilder)角色:担任那个角色的是与应用程序紧密相关的一些类,它们在应用程序的调用下创建产品的实例。那个角色产品实现了抽象建筑者接口,要紧完成分部创建产品并提供产品对象的实例。3、导演者(Dictor)角色:顾名思义,确实是具体指挥使用哪个具体制造者来完成产品的创建,是创建工作的调用者。然而,导演者角色并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建筑者角色。4、产品(Prouct)角色:产品角色确实是建筑中的复杂对象。一般只有关于复杂对象的创建才使用建筑者模式,一个系统中会出现多于一个的产品类
52、,而这些产品类并不一定有共同的接口,可能完全不关联,这时就需要提供多套抽象和具体的建筑者来完成不一致的产品的创建或者是采纳一个统一接口来标识产品,我个人推举前者。请大伙儿注意,那个地点的产品只是一个产品类,不存在继承关系,因此也就没有像抽象工厂中的那种客户端依靠抽象的讲法了。模式原型代码:Bildr patter codein C#/建筑者模式usingyst;usingystem.ollections;nmescDesignPaterns.reationa/应用程序测试publicclassMiApppicstaticvodMain()/创建导演者和具体建筑者角色Directodirecto
53、r=newDirectr();Buileb=ConteBuilde1();Bude2=newConcrteBildr2();/依照两个建筑者获得产品类,注意应用程序直接使用产品类directo.ontuct();rodctp1=b.Getesult();p.hw();directr.onstuc(b2);Productp2=b2Geteult();p2Shw();/等待输入Console.Read();/导演者角色classDrecr/导演者调用建筑者分部创建,注意具体的创建顺序由导演者决定ubliodCtrc(Bilerbuildr)ilerBuilart();bulderBuildPart
54、B();/抽象建筑者abtrclassBuildepublicabstcvodBilA();publistrctvoiBuildPat();publicastactProdutGetResult();/具体建筑者1clanrtBilde1:uideritePodctpoduct=newroduct();pblicoveridevidBuildParA()pduc.Ad(at);blicoverrideoiBldPrt()rodct.Add(tB);pcoerridPouctGesult()eupuc;/具体建筑者classCoceeBilder2:BuildrprivaeProducrouct
55、=ewProdct();publicerrdidBuilPartA()rodct.Add(rt);publioverididBuildatB()product.dd(PrY);publicoverrideProductGetReslt()returrdut;/产品类classProdctArraystparts=nerayLt();pulicoidA(trart)parts.Ad(part);blicvoiShw()onsle.WritLie(PoductPars-);foeach(trinpatnpa)ConeWriteLine(part);输出结果为:Prduct Part-ParArPr
56、oduct Pats -PrtXrt生活中的实例:那个小例子向大伙儿展示了一辆车是如何利用建筑者模式被创建的,注意商店(那个地点确实是导演者)是如何利用hieBuilders按照一定的顺序创建一辆车的。ReaorlodesigbsrcFatory in C#/建筑者模式应用小例子usigSstem;usiysem.Colens.Geei;naesaceesinPatens.CtionaBildeRalWor/主应用程序pubicclassMaiAppublicstaticvoiMain()Vehiluildrbuier;/利用具体Builder创建商店对象hophop=newShop();/踏
57、板车建筑者buider=newScotrulder();sp.Consruct(build);buldr.ehicle.how();/小汽车建筑者builder=nwCarBuilder();soConstruct(bilder);builde.Vehice.Sow();/摩托车建筑者buil=newMooCycleBuler();shoponsrut(bider);bildr.Vehic.ho();/等待用户输入Cnsoe.Redey();/商店类,相当于导演者角色cassSop/通过一个复杂的建筑过程pubivoidCtruc(VehcleBidevehicleBuder)hicleBud
58、er.ulFrame();ehcleBulder.uidngn();veiceBider.BldWeels();vhileBuildrBuiloors();/车辆建筑者,相当于抽象建筑者角色absraclssVehiceBuilderprotecedVhiclvehicle;/获得车辆产品实例pubicehileVehilgetreturvehicle;/分部建筑方法ubliabstraidBuildrae();publiabtravoiBuildEngie();plicbstractvidBuilWels();publiabsacvodBilDoors();/摩托车建筑者,相当于一个具体建筑
59、者角色lasotoCceBuilde:VhicleudepubliMotrCycleuilde()vehil=newhie(torCyc);publcoverieoidBuilrame()vehclefae=ooCclFme;ublicoveeiduildEngine()veicleengie=500c;picoverididBuildhels()veiewhels=;pulicvrdvidBuidDoors()vhcledors0;/小汽车建筑者,相当于一个具体建筑者角色clsCarBilder:ileBuildrpublicarBuilder()vehicl=nwVehie(Cr);pub
60、licoverodBuildFrame()vehcler=Carame;uicoerrieoiBuilEngine()vicleene=250;publcvrrideidBildWel()vehiclewheel=4;publcoverdevoidBuildDoors()vehicldoors4;/踏板车建筑者,相当于一个具体建筑者角色lassScootuiler:VehcleuildepuicSootrudr()veiclenewhce(coote);pbliovededBuildrae()ehiclefae=SoerFram;ublverivoidBuldEnne()vehilengine
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 赛事直播服务合同
- 蛋糕装饰师保密意识模拟考核试卷含答案
- 农化技术员操作规程模拟考核试卷含答案
- 燃气管网运行工岗前安全宣传考核试卷含答案
- 营林试验员安全防护模拟考核试卷含答案
- 松香蒸馏工安全行为测试考核试卷含答案
- 沼气生产工安全综合评优考核试卷含答案
- 兴趣点地理信息采集员岗位离岗考核试卷含答案
- 冷压延工安全生产意识测试考核试卷含答案
- 生活垃圾收集工岗中质量考核试卷含答案
- GB/T 19973.2-2025医疗产品灭菌微生物学方法第2部分:用于灭菌过程的定义、确认和维护的无菌试验
- JJF(津)118-2024 分布式光纤振动传感系统计量校准规范
- DB11T 211-2017 园林绿化用植物材料 木本苗
- Chapter-1工程英语翻译概述
- 2024年大学生创新创业训练计划流程
- 江堤绿化养护投标方案(技术方案)
- 新教师如何备课课件
- 民航服务心理学高职PPT完整全套教学课件
- “千名医师下基层”对口支援活动工作鉴定表
- 人教版五年级语文上册全册完整课件【下载】
- 网格系统中英文双语版grid systems an english-chinese version
评论
0/150
提交评论