抽象工厂设计模式示例

本文是我们名为“ Java设计模式 ”的学院课程的一部分。

在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因,并了解何时以及如何应用模式中的每一个。 在这里查看 !

目录

1.简介 2.什么是抽象工厂设计模式 3.实施抽象工厂设计模式 4.何时使用抽象工厂设计模式 5. JDK中的抽象工厂模式 6.下载源代码

1.简介

在上一课中 ,我们为一家产品公司开发了一个应用程序,用于解析XML并将结果显示给他们。 为此,我们为公司与其客户之间的不同通信类型创建了不同的解析器。 我们使用工厂方法设计模式来解决他们的问题。

该应用程序适合他们。 但是现在客户不想遵循公司的特定XML规则。 客户希望使用自己的XML规则与产品公司进行通信。 这意味着对于每个客户,公司都应具有客户特定的XML解析器。 例如,对于NY客户端,应该有四种特定类型的XML解析器,即NYErrorXMLParser,NYFeedbackXML,NYOrderXMLParser,NYResponseXMLParser和TW客户端的四种不同的解析器。

公司已要求您根据新要求更改应用程序。 为了开发解析器应用程序,我们使用了工厂方法设计模式,其中要使用的确切对象由子类根据解析器的类型决定。 现在,为了实现这一新要求,我们将使用工厂工厂,即抽象工厂。

这次我们需要根据客户端特定的XML进行解析器,因此我们将为不同的客户端创建不同的工厂,这将为我们提供要解析的客户端特定的XML。 为此,我们将创建一个抽象工厂,然后实现该工厂以提供特定于客户的XML工厂。 然后,我们将使用该工厂来获取所需的客户端特定的XML解析器对象。

抽象工厂是我们选择的设计模式,在实现它来解决我们的问题之前,请让我们进一步了解它。

2.什么是抽象工厂设计模式

抽象工厂(AKA Kit)是一种设计模式,它提供了一个接口,用于创建相关或相关对象的族,而无需指定其具体类。 抽象工厂模式将“工厂方法模式”的概念提高到了一个新的水平。 抽象工厂是一个类,提供提供产生一系列对象的接口。 在Java中,可以使用接口或抽象类来实现它。

当客户对象想要创建一组相关的相关类的实例,而又不必知道要实例化哪个具体的具体类时,抽象工厂模式很有用。 不同的具体工厂实现抽象工厂接口。 客户对象利用这些具体工厂来创建对象,因此不需要知道实际实例化了哪个具体类。

抽象工厂可用于插入不同的对象组以更改系统的行为。 对于每个小组或家庭,都将建立一个具体工厂来管理对象的创建以及它们之间的相互依赖性和一致性要求。 每个具体工厂都实现抽象工厂的接口

class_diagram_1

图1

抽象工厂

  • 声明用于创建抽象产品对象的操作的接口。

混凝土工厂

  • 实施操作以创建具体的产品对象。

抽象产品

  • 声明一种产品对象的接口。

混凝土产品

  • 定义要由相应的混凝土工厂创建的产品对象。
  • 实现AbstractProduct接口。

客户

  • 仅使用由AbstractFactory和AbstractProduct类声明的接口。

3.实施抽象工厂设计模式

为了实现抽象工厂设计模式,我们将首先创建一个将由所有具体工厂实现的接口。

package com.javacodegeeks.patterns.abstractfactorypattern;public interface AbstractParserFactory {public XMLParser getParserInstance(String parserType);
}

上面的接口由客户端特定的具体工厂实现,该工厂将向客户端对象提供XML解析器对象。 getParserInstance方法使用parserType作为参数,该参数用于获取特定于消息的(错误解析器,订单解析器等)解析器对象。

两个特定于客户端的具体解析器工厂是:

package com.javacodegeeks.patterns.abstractfactorypattern;public class NYParserFactory implements AbstractParserFactory {@Overridepublic XMLParser getParserInstance(String parserType) {switch(parserType){case "NYERROR": return new NYErrorXMLParser();case "NYFEEDBACK": return new NYFeedbackXMLParser ();case "NYORDER": return new NYOrderXMLParser();case "NYRESPONSE": return new NYResponseXMLParser();}return null;}}
package com.javacodegeeks.patterns.abstractfactorypattern;public class TWParserFactory implements AbstractParserFactory {@Overridepublic XMLParser getParserInstance(String parserType) {switch(parserType){case "TWERROR": return new TWErrorXMLParser();case "TWFEEDBACK": return new TWFeedbackXMLParser ();case "TWORDER": return new TWOrderXMLParser();case "TWRESPONSE": return new TWResponseXMLParser();}return null;}}

上面的两个工厂实现了AbstractParserFactory接口,并覆盖了getParserInstance方法。 它根据参数中请求的解析器​​类型返回特定于客户端的解析器对象。

package com.javacodegeeks.patterns.abstractfactorypattern;public interface XMLParser {public String parse();}

上面的接口由具体的解析器类实现,以解析XML并返回字符串消息。

该公司与其客户之间有两个客户以及四种不同类型的消息交换。 因此,应该有六种不同类型的特定于客户端的XML解析器。

package com.javacodegeeks.patterns.abstractfactorypattern;public class NYErrorXMLParser implements XMLParser{@Overridepublic String parse() {System.out.println("NY Parsing error XML...");return "NY Error XML Message";}}
package com.javacodegeeks.patterns.abstractfactorypattern;public class NYFeedbackXMLParser implements XMLParser{@Overridepublic String parse() {System.out.println("NY Parsing feedback XML...");return "NY Feedback XML Message";}}
package com.javacodegeeks.patterns.abstractfactorypattern;public class NYOrderXMLParser implements XMLParser{@Overridepublic String parse() {System.out.println("NY Parsing order XML...");return "NY Order XML Message";}}
package com.javacodegeeks.patterns.abstractfactorypattern;public class NYResponseXMLParser implements XMLParser{@Overridepublic String parse() {System.out.println("NY Parsing response XML...");return "NY Response XML Message";}}
package com.javacodegeeks.patterns.abstractfactorypattern;public class TWErrorXMLParser implements XMLParser{@Overridepublic String parse() {System.out.println("TW Parsing error XML...");return "TW Error XML Message";}}
package com.javacodegeeks.patterns.abstractfactorypattern;public class TWFeedbackXMLParser implements XMLParser{@Overridepublic String parse() {System.out.println("TW Parsing feedback XML...");return "TW Feedback XML Message";}}
package com.javacodegeeks.patterns.abstractfactorypattern;public class TWOrderXMLParser implements XMLParser{@Overridepublic String parse() {System.out.println("TW Parsing order XML...");return "TW Order XML Message";}}
package com.javacodegeeks.patterns.abstractfactorypattern;public class TWResponseXMLParser implements XMLParser{@Overridepublic String parse() {System.out.println("TW Parsing response XML...");return "TW Response XML Message";}}

为了避免客户代码和工厂之间的依赖性,可选地,我们实现了一个工厂生产者,该生产者具有静态方法,并负责向客户对象提供所需的工厂对象。

package com.javacodegeeks.patterns.abstractfactorypattern;public final class ParserFactoryProducer {private ParserFactoryProducer(){throw new AssertionError();}public static AbstractParserFactory getFactory(String factoryType){switch(factoryType){case "NYFactory": return new NYParserFactory();case "TWFactory": return new TWParserFactory();}return null;}}

现在,让我们测试代码。

package com.javacodegeeks.patterns.abstractfactorypattern;public class TestAbstractFactoryPattern {public static void main(String[] args) {AbstractParserFactory parserFactory = ParserFactoryProducer.getFactory("NYFactory");XMLParser parser = parserFactory.getParserInstance("NYORDER");String msg="";msg = parser.parse();System.out.println(msg);System.out.println("************************************");parserFactory = ParserFactoryProducer.getFactory("TWFactory");parser = parserFactory.getParserInstance("TWFEEDBACK");msg = parser.parse();System.out.println(msg);}}

上面的代码将导致以下输出:

NY Parsing order XML...
NY Order XML Message
************************************
TW Parsing feedback XML...
TW Feedback XML Message

在上面的课程中,我们首先从工厂生产商那里获得了NY工厂,然后从NY分析器工厂获得了Order XML分析器。 然后,我们在解析器对象上调用了parse方法,并显示了返回消息。 正如输出中清楚显示的那样,我们为TW客户执行了相同的操作。

4.何时使用抽象工厂设计模式

在以下情况下使用抽象工厂模式

  • 系统应独立于其产品的创建,组成和表示方式。
  • 系统应配置有多个产品系列之一。
  • 相关产品对象系列旨在一起使用,因此您需要强制执行此约束。
  • 您想提供产品的类库,并且只想显示它们的接口,而不是它们的实现。

5. JDK中的抽象工厂模式

  • java.util.Calendar#getInstance()
  • java.util.Arrays#asList()
  • java.util.ResourceBundle#getBundle()
  • java.sql.DriverManager#getConnection()
  • java.sql.Connection#createStatement()
  • java.sql.Statement#executeQuery()
  • java.text.NumberFormat#getInstance()
  • javax.xml.transform.TransformerFactory#newInstance()

6.下载源代码

这是关于“抽象工厂设计模式”的课程。 您可以在此处下载源代码: AbstractFactoryPattern-Project

翻译自: https://www.javacodegeeks.com/2015/09/abstract-factory-design-pattern.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/357157.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《javaScript100例|03》自写javaScript+CSS轮显效果

目录 效果图 代码示例 源码地址&#xff1a;自写JsCSS轮显效果.rar-互联网文档类资源-CSDN下载https://download.csdn.net/download/weixin_41937552/37380520 效果图 代码示例 <html xmlns"http://www.w3.org/1999/xhtml"> <head> <meta http-equ…

linux shell 指令 诸如-d, -f, -e之类的判断表达式

文件比较运算符-e filename 如果 filename存在&#xff0c;则为真 [ -e /var/log/syslog ]-d filename 如果 filename为目录&#xff0c;则为真 [ -d /tmp/mydir ]-f filename 如果 filename为常规文件&#xff0c;则为真 [ -f /usr/bin/grep ]-L filename 如果 filenam…

《javaScript100例|04》自动播放——Js幻灯片缓冲效果

目录 效果图 示例 源码地址&#xff1a; 效果图 示例 <html> <head> <title>自动播放——幻灯片缓冲效果</title> <style> body,div,ul,li{margin:0;padding:0;} ul{list-style-type:none;} body{background:#000;text-align:center;font:12p…

每周必写

这周没有上课&#xff0c;阅读了《代码大全》第六章模块化设计 内聚性和耦合性 模块化设计的目标是使每个子程序都成为一个“黑盒子”&#xff0c;你知道进入盒子和从盒子里出来 的是什么&#xff0c;却不知道里边发生什么。它的接口非常简单&#xff0c;功能明确&#xff0c;对…

eclipse鼠标变十了_Eclipse在过去十年中的主要成就

eclipse鼠标变十了正如我所写的那样 &#xff0c;Eclipse在11月庆祝了10年来的开源和社区。 Eclipse社区已经形成了许多里程碑 &#xff0c;但是主要成就是什么&#xff1f; Eclipse为实际改变软件行业做了什么&#xff1f; 这是我认为Eclipse的一些关键成就。 1.主导的Java ID…

vue安装教程及简介

Vue.js 是一套构建用户界面的渐进式框架。只关注视图层, 采用自底向上增量开发的设计。 目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。Vue 学习起来非常简单。 目录 常用的vue.js版本及方法 学习vue之前需要掌握基础html+css+javaScript知识。 比如: …

Spring和Amazon Web Services

如今&#xff0c; Amazon Web Services &#xff08;或AWS&#xff09;是要使用和部署到的基础架构和硬件提供商的最常见选择之一。 许多Spring应用程序已经解决了集成应用程序基础结构和底层的挑战。 这些内部解决方案在设计和实际功能方面在复杂性和复杂程度方面有所不同。 这…

学习进度条15

第十五周 所花时间&#xff08;包括上课&#xff09; 周一上午 8&#xff1a;00-9&#xff1a;50 上课 周一下午 13&#xff1a;00-14&#xff1a;00阅读人月神话 周五下午 15&#xff1a;30-17&#xff1a;30 整理本月期的所有作业 周六上午10&#xff1a;00-12&#xff1a;…

vue目录结构及简单的开发介绍

熟悉vue项目的目录结构,在一定程度上能提高我的开发效率及查找文件的速度。 这里比较推荐使用VS code编译器,HBuild-x,webstorm等编译器相比之下逊色不少,用过的就知道有多香。 目录 Vue.js 目录结构 目录说明 VUE入门基本操作 Vue.js 模板语法

PHP+jquery 树状菜单

本项目开发过程中涉及树状菜单&#xff0c;于是做如下分享菜单实现 不足之处请大牛指点并见谅&#xff08;如图&#xff09; 1&#xff1a;数据表涉及字段 id int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 系统菜单ID, pid int(10) DEFAULT NULL COMMENT 父级ID, name va…

vue条件语句与循环语句的基本使用

目录 Vue.js 条件语句 Vue.js 循环语句 Vue.js 条件语句 条件判断使用 v-if 指令 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue 测试实例 - 孙叫兽的博客</title> <script src="https://cdn.s…

javaone_虚拟化Java应用程序:最佳实践(JavaOne 2011)

javaone贾斯汀穆雷&#xff08;Justin Murray&#xff09;早五分钟就开始了他的演讲[“虚拟化Java应用程序&#xff1a;最佳实践”&#xff08;21860&#xff09;]&#xff0c;并说虚拟化已经到了人们不再需要担心利用虚拟化的地步。 他说他的演讲大约有一年的历史了&#xff0…

vue计算属性computed与监听属性watch的基本使用

目录 Vue.js 计算属性 Vue.js 监听属性 Vue.js 计算属性 计算属性关键词: computed。 计算属性在处理一些复杂逻辑时是很有用的。 反转字符串的示例 <!DOCTYPE html> <html> <he

连接(交叉连接、内连接、外连接、自连接)

本文非原创 可分为&#xff1a;交叉连接、内连接、外连接、自连接 1.使用交叉连接&#xff1a; 它是非限制连接&#xff0c;就是将两个表格不加任何条件的组合在一起&#xff0c; 即第一个表格的所有记录分别和第二个表格的每一条记录相连接 组合成新的记录&#xff0c;连接后结…

vue样式绑定与事件处理器的基本使用

目录 Vue.js 样式绑定 Vue.js 事件处理器 事件修饰符 Vue.js 样式绑定

Finally 与 return

网上有很多人探讨Java中异常捕获机制try...catch...finally块中的finally语句是不是一定会被执行&#xff1f;很多人都说不是&#xff0c;当然他们的回答是正确的&#xff0c;经过我试验&#xff0c;至少有两种情况下finally语句是不会被执行的&#xff1a; &#xff08;1&…

vue表单的基本使用

Vue.js 表单 介绍 一下Vue.js 表单上的应用。你可以用 v-model 指令在表单控件元素上创建双向数据绑定。 v-model 会根据控件类型自动选取正确的方法来更新元素。 input 和 textarea 元素中使用 v-model 实现双向数据绑定: <!DOCTYPE html> <html> <head…

fold函数_Java中使用Map and Fold进行函数式编程

fold函数在函数式编程中&#xff0c;Map和Fold是两个非常有用的运算符&#xff0c;它们属于每种函数式语言。 如果Map和Fold运算符是如此强大且必不可少&#xff0c;那么您如何解释说即使Java编程语言缺少这两个运算符&#xff0c;我们也可以使用Java来完成工作&#xff1f; 事…

NVIC优先级分组

挂起&#xff0c;解挂&#xff0c;使能&#xff0c;失能 转载于:https://www.cnblogs.com/alantechnique/p/5598374.html

Vue组件及自定义事件

目录 Vue.js 组件 动态 Prop Prop 验证 Vue.js 组件 - 自定义事件 data 必须是一个函数