java工厂设计模式.ppt

上传人:max****ui 文档编号:8621466 上传时间:2020-03-30 格式:PPT 页数:50 大小:1.16MB
返回 下载 相关 举报
java工厂设计模式.ppt_第1页
第1页 / 共50页
java工厂设计模式.ppt_第2页
第2页 / 共50页
java工厂设计模式.ppt_第3页
第3页 / 共50页
点击查看更多>>
资源描述
TheFactoryPattern 工厂模式 学习问题 随着经济的全球化 一个软件可能要在全球销售 因此 我们设计的软件应该能够通过简单的配置就可以适应不同的国家 本讲所学的知识将能提供一种有助于解决此问题的方法 对象创建问题 关于new 按照面向抽象的设计原则 我们应该面向接口编程而不是面向实现编程 但是我们每次使用new时 是不是正在违背这一原则呢 我们想用接口 但却必须建立一个具体类的实例 Duckduck newMallardDuck 问题 当你拥有一组相关的具体类时 你常常被迫写出类似下面的代码 Duckduck If picnic duck newMallardDuck elseif hunting duck newDecoyDuck elseif inBathTub duck newRubberDuck 这样做的原因是直到运行时我们才知道需要实例化那个类 这样做的后果是如果应用要做变化或扩展 往往要修改这段代码 这使得维护困难并容易引入错误 问题在哪里 是new的问题吗 从技术上来说 new并没有任何问题 new是java最基本的部分 真正的问题在于 变化 如果对接口编程 我们可实现与许多 变化 的隔离 因为通过多态机制 你的代码对于实现接口的新类依然适用 但是使用具体类麻烦就来了 因为增加新的具体类时相应代码可能就必须修改 怎么办呢 Duckduck newMallardDuck 上面这段代码所在的模块与MallardDuck模块形成了耦合 再回忆我们前面提出的面向对象设计的原则 识别应用的变化部分 并将之与固定的部分相分离 区分变化的部分 下面我们来看一个例子Pizza店 披萨 PizzaStore类中的一段代码 订做pizza PublicClassPizzaStore PizzaorderPizza Pizzapizza newPizza pizza prepare pizza bake pizza cut pizza box returnpizza 真希望这是一个抽象类或者接口 可惜抽象类或接口都不能被实例化 而且 我们有许多种pizza 所以我们增加一些代码 来确定合适的pizza种类 然后进行制作 修改后的代码 PizzaorderPizza Stringtype Pizzapizza if type equals cheese pizza newCheesePizza elseif type equals greek pizza newGreekPizza elseif type equals pepperoni pizza newPepperoniPizza pizza prepare pizza bake pizza cut pizza box returnpizza 根据接受的类型 创建相应的pizza实例 并赋值给实例变量 注意 各种pizza实现接口Pizza 传递pizza的类型给方法orderPizza 每一种pizza子类型都知道其制作方法 由于市场竞争 其他pizza店推出了新产品 我们也得增加 例如VeggiePizza GreekPizza最近不受欢迎 把它从菜单中取消 于是 改 改 改 PizzaorderPizza Stringtype Pizzapizza if type equals cheese pizza newCheesePizza elseif type equals greek pizza newGreekPizza elseif type equals pepperoni pizza newPepperoniPizza elseif type equals veggie pizza newVeggiePizza pizza prepare pizza bake pizza cut pizza box returnpizza 变与不变 变与不变 PizzaorderPizza Stringtype Pizzapizza if type equals cheese pizza newCheesePizza elseif type equals greek pizza newGreekPizza elseif type equals pepperoni pizza newPepperoniPizza elseif type equals veggie pizza newVeggiePizza pizza prepare pizza bake pizza cut pizza box returnpizza 这是变化的部分 随着Pizza菜单的变化 这部分要跟着不断地变 这部分是不变的部分 分离 PizzaorderPizza Stringtype Pizzapizza if type equals cheese pizza newCheesePizza elseif type equals greek pizza newGreekPizza elseif type equals pepperoni pizza newPepperoniPizza elseif type equals veggie pizza newVeggiePizza pizza prepare pizza bake pizza cut pizza box returnpizza 把这部分封装在一个只管如何创建pizza的对象中 if type equals cheese pizza newCheesePizza elseif type equals greek pizza newGreekPizza elseif type equals pepperoni pizza newPepperoniPizza elseif type equals veggie pizza newVeggiePizza 将创建pizza对象的代码从orderPizza方法中分离出去 专管制作pizza的对象 我们将专管制作pizza的对象叫做Pizza工厂 PizzaorderPizza Stringtype Pizzapizza pizza prepare pizza bake pizza cut pizza box returnpizza PizzaFactory 要求制作pizza pizza 这样 orderPizza方法就成为PizaFactory的客户 Pizza工厂 SimplePizzaFactory publicclassSimplePizzaFactory publicPizzacreatePizza Stringtype Pizzapizza null if type equals cheese pizza newCheesePizza elseif type equals pepperoni pizza newPepperoniPizza elseif type equals veggie pizza newVeggiePizza returnpizza Pizza工厂中定义了 生产 pizza的方法 所有客户都可以用它来实例化新的pizza对象 这部分代码就是从orderPizza 方法中抽出来的 和原来的方法一样 也是通过参数确定pizza的种类 思考一下 这看来好像我们只是把问题从一个对象推给了另一个对象 这样做有什么好处呢 可以解除客户代码 PizzaStore 与具体Pizza的耦合 SimplePizzaFactory可以有许多个客户 这样 当实现改变时我们只需要修改SimplePizzaFactory 而不需修改众多的客户 提高了聚合度 PizzaStore的职责是使用pizza对象 SimplePizzaFactory的职责是决定创建什么样的pizza对象 重写PizzaStore类 publicclassPizzaStore SimplePizzaFactoryfactory publicPizzaStore SimplePizzaFactoryfactory this factory factory publicPizzaorderPizza Stringtype Pizzapizza pizza factory createPizza type pizza prepare pizza bake pizza cut pizza box returnpizza othermethodshere 简单工厂模式 Pizza可以是一个抽象类 也可以是一个接口 框架 框架的对外接口 简单工厂模式 有人认为这还不是一个真正的模式 只是一种程序设计的习惯 授权pizza店 我们的pizza店非常成功 许多人都想开设我们的授权加盟店 但是 不同地区的加盟pizza店可能希望供应不同口味的pizza 怎么解决这个问题呢 解决方法之一 建立不同的工厂 建立不同的工厂 如NYPizzaFactory ChicagoPizzaFactory CaliforniaPizzaFactory 在PizzaStore中包含相应工厂的实例 其代码类似于 该pizza店提供纽约风味的pizzaNYPizzaFactorynyFactory newNYPizzaFactory 建立一个生产纽约风味pizza的工厂PizzaStorenyStore newPizzaStore nyFactory 建立一个pizza店 引用纽约风味pizza的工厂nyStore orderPizza Veggie 生产的是纽约风味的pizza 该pizza店提供芝加哥风味的pizzaChicagoPizzaFactorychicagoFactory newChicagoPizzaFactory PizzaStorechicagoStore newPizzaStore chicagoFactory chicagoStore orderPizza Veggie 抽象工厂模式 这么多工厂 可以再增加抽象层让我们一起来设计 另一种解决方法 工厂方法模式 思路 改写的PizzaStore 将createPizza 方法放回到PizzaStore 但是声明为抽象方法 然后 为每一种地方风味创建一个PizzaStore的子类 改造后的PizzaStore的代码 publicabstractclassPizzaStore publicPizzaorderPizza Stringtype Pizzapizza createPizza type pizza prepare pizza bake pizza cut pizza box returnpizza abstractPizzacreatePizza Stringtype 在PizzaStore内调用自身的一个方法来制造pizza 而不是使用一个factory对象 factory对象成了这里的一个抽象方法 下面我们需要PizzaStore的各种子类 对应不同的地区风味 让子类做决定 ChicagoPizzaStore createPizza PizzacreatePizza Stringitem if item equals 奶酪 returnnewNYStyleCheesePizza elseif item equals 蔬菜 returnnewNYStyleVeggiePizza elseif item equals 卡姆 returnnewNYStyleClamPizza elseif item equals 辣香肠 returnnewNYStylePepperoniPizza elsereturnnull 讨论 为什么说是由子类做决定的 ChicagoPizzaStore createPizza publicabstractclassPizzaStore publicPizzaorderPizza Stringtype Pizzapizza createPizza type pizza prepare pizza bake pizza cut pizza box returnpizza abstractPizzacreatePizza Stringtype 现在让我们来编写子类NYPizzaStore ChicagoPizzaStore createPizza publicclassNYPizzaStoreextendsPizzaStore PizzacreatePizza Stringitem if item equals 奶酪 returnnewNYStyleCheesePizza elseif item equals 蔬菜 returnnewNYStyleVeggiePizza elseif item equals 卡姆 returnnewNYStyleClamPizza elseif item equals 辣香肠 returnnewNYStylePepperoniPizza elsereturnnull 怎么编写子类ChicagoPizzaStore 试试看 声明工厂方法 publicabstractclassPizzaStore publicPizzaorderPizza Stringtype Pizzapizza createPizza type pizza prepare pizza bake pizza cut pizza box returnpizza abstractPizzacreatePizza Stringtype 实例化pizza的责任现在由一个方法承担 该方法相当于一个工厂 我们称之为工厂方法 PizzaStore的子类用createPizza 方法处理对象的实例化 声明工厂方法 abstractPizzacreatePizza Stringtype abstractProductfactoryMethod Stringtype 工厂方法是抽象的 在一个超类中定义 必须由子类来实现 工厂方法返回一个产品 该产品通常在其所在类的方法中定义 如orderPizza 工厂方法通常提供参数 用以选择一个产品的不同品种 工厂方法将客户 超类中的方法 如PizzaStore中的orderPizza 与具体的产品相隔离 工厂方法怎么工作 假定张三喜欢纽约风味的pizza 李四喜欢芝加哥风味的pizza 需要相应Pizza店的实例调用orderPizza 订购想要的pizza品种createPizza 被调用 并返回pizza到orderPizza 方法 尽管不知道是什么pizza 但orderPizza 仍知道对它进行后续处理 以张三订购pizza为例 PizzaStorenyPizzaStore newNYPizzaStore nyPizzaStore orderPizza cheese 在orderPizza 方法中Pizzapizza createPizza cheese 在orderPizza 方法中pizza prepare pizza bake pizza cut pizza box 忘记了产品 pizza 先来个抽象的 importjava util ArrayList publicabstractclassPizza Stringname Stringdough 生面团Stringsauce ArrayListtoppings newArrayList voidprepare System out println Preparing name System out println Tossingdough System out println Addingsauce System out println Addingtoppings for inti 0 i toppings size i System out println toppings get i voidbake System out println Bakefor25minutesat350 voidcut System out println Cuttingthepizzaintodiagonalslices voidbox System out println PlacepizzainofficialPizzaStorebox publicStringgetName returnname 再来个具体的 publicclassNYStyleCheesePizzaextendsPizza publicNYStyleCheesePizza name NYStyleSauceandCheesePizza dough ThinCrustDough sauce MarinaraSauce toppings add GratedReggianoCheese Marinara mariner s sauceisanItalianredsauceusuallymadewithtomatoes garlic herbs suchasbasil andonion 再来个另一风味的 publicclassChicagoStyleCheesePizzaextendsPizza publicChicagoStyleCheesePizza name ChicagoStyleDeepDishCheesePizza dough ExtraThickCrustDough sauce PlumTomatoSauce toppings add ShreddedMozzarellaCheese voidcut System out println Cuttingthepizzaintosquareslices 测试主类 publicclassPizzaTestDrive publicstaticvoidmain String args PizzaStorenyStore newNYPizzaStore PizzaStorechicagoStore newChicagoPizzaStore Pizzapizza nyStore orderPizza cheese System out println 张三ordereda pizza getName n pizza chicagoStore orderPizza cheese System out println 李四ordereda pizza getName n 工厂方法模式中的类 创建者类TheCreatorclasses ChicagoPizzaStore createPizza Abstractcreator Concretecreators 工厂方法模式中的类 产品类TheProductclasses Abstractproduct Concreteproducts 工厂方法模式的正式定义 在类中定义一个用于创建对象的接口方法 让其子类决定实例化哪一个类 通过这种做法 使得工厂方法的客户 工厂方法的使用者 不必了解具体应该实例化哪一个类 如 pizza pizzaStore orderPizza cheese 生产出来的匹萨是纽约风味的还是芝加哥风味的取决于pizzaStore引用的是哪个PizzaStore的子类 工厂方法模式的结构 总结 FactoryMethod模式 意图定义一个用于创建对象的接口 让子类决定实例化哪一个类 工厂方法模式让一个类的实例化延迟到其子类 使得对象的创建与对象的使用分离开来 别名虚拟构造器 工厂方法模式的优点与适用场景 优点让用户代码与特定类Product的子类ConcretProduct的代码解耦 用户不必知道它所使用的对象是怎么创建的 只需要知道这些对象的用法即可 适用场景希望让用户使用某些类 但不希望与这些类形成耦合 用new 用户需要一个类的子类的实例 但不知道该类有哪些子类可用 工厂方法模式的好处 用户程序只需要和这些类打交道 总结 FactoryMethod 参与者 Product document 定义工厂方法所创建对象的接口 ConcreteProduct mydocument 实现product接口 Creator application 声明工厂方法可以调用工厂方法以创建一个product对象ConcreteCreator MyApplication 重新定义工厂方法 以返回一个ConcreteProduct实例 工厂方法的经典范例 java迭代器 Collection接口中定义了iterator 方法 所有的集合类都实现了这个方法 iterator 方法就是一个工厂方法 其使用者不必了解需要实例化哪个类 importjava util publicclassShowIterator publicstaticvoidmain String args Listlist Arrays asList newString fountaun rocket tree Iteratoriter list iterator while iter hasNext System out println iter next 抽象工厂解决的问题 抽象工厂模式是避免必须修改所有new调用问题的一个有效策略 抽象工厂的所有具体化有一个共同的主题 使用工厂来创建实现了已知接口 但类型尚不明确的对象 抽象工厂一般与单例模式联系在一起 由单例模式获得抽象工厂 由抽象工厂制造实际类型未知的产品对象 经典例句Imageim Toolkit getDefaultToolkit createImage i 每次调用getDefaultToolkit 方法得到的是同一个Toolkit实例 createImage 是Toolkit的一个方法 习题 上机完成 某连锁超市为留住顾客 决定发行会员卡 会员卡分为金卡 银卡 普通卡等多种类型 卡的类型可能还会增加 不论是什么卡 其编号都是统一编制的 即使用同一个编号序列 某软件公司承接了该项目 设计人员觉得应该将系统设计的具有一定的通用性 不仅可以较方便的应对该连锁店的需求变化 增减卡的类型 而且可以较容易的修改扩展 为其他公司提供发卡 卡的风格可能不同 服务 假定你是该软件公司的设计师 请你运用学过的设计模式设计该系统的架构 编写实验报告 要求画出相应的类图 提供示意性java源程序 实验报告发至sam84149
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!