本文是我们名为“ Java设计模式 ”的学院课程的一部分。
在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因,并了解何时以及如何应用模式中的每一个。 在这里查看 !
1.简介
在上一课中 ,我们为一家产品公司开发了一个应用程序,用于解析XML并将结果显示给他们。 为此,我们为公司与其客户之间的不同通信类型创建了不同的解析器。 我们使用工厂方法设计模式来解决他们的问题。
该应用程序适合他们。 但是现在客户不想遵循公司的特定XML规则。 客户希望使用自己的XML规则与产品公司进行通信。 这意味着对于每个客户,公司都应具有客户特定的XML解析器。 例如,对于NY客户端,应该有四种特定类型的XML解析器,即NYErrorXMLParser,NYFeedbackXML,NYOrderXMLParser,NYResponseXMLParser和TW客户端的四种不同的解析器。
公司已要求您根据新要求更改应用程序。 为了开发解析器应用程序,我们使用了工厂方法设计模式,其中要使用的确切对象由子类根据解析器的类型决定。 现在,为了实现这一新要求,我们将使用工厂工厂,即抽象工厂。
这次我们需要根据客户端特定的XML进行解析器,因此我们将为不同的客户端创建不同的工厂,这将为我们提供要解析的客户端特定的XML。 为此,我们将创建一个抽象工厂,然后实现该工厂以提供特定于客户的XML工厂。 然后,我们将使用该工厂来获取所需的客户端特定的XML解析器对象。
抽象工厂是我们选择的设计模式,在实现它来解决我们的问题之前,请让我们进一步了解它。
2.什么是抽象工厂设计模式
抽象工厂(AKA Kit)是一种设计模式,它提供了一个接口,用于创建相关或相关对象的族,而无需指定其具体类。 抽象工厂模式将“工厂方法模式”的概念提高到了一个新的水平。 抽象工厂是一个类,提供提供产生一系列对象的接口。 在Java中,可以使用接口或抽象类来实现它。
当客户对象想要创建一组相关的相关类的实例,而又不必知道要实例化哪个具体的具体类时,抽象工厂模式很有用。 不同的具体工厂实现抽象工厂接口。 客户对象利用这些具体工厂来创建对象,因此不需要知道实际实例化了哪个具体类。
抽象工厂可用于插入不同的对象组以更改系统的行为。 对于每个小组或家庭,都将建立一个具体工厂来管理对象的创建以及它们之间的相互依赖性和一致性要求。 每个具体工厂都实现抽象工厂的接口
抽象工厂
- 声明用于创建抽象产品对象的操作的接口。
混凝土工厂
- 实施操作以创建具体的产品对象。
抽象产品
- 声明一种产品对象的接口。
混凝土产品
- 定义要由相应的混凝土工厂创建的产品对象。
- 实现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 {
@Override
public 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 {
@Override
public 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{
@Override
public String parse() {
System.out.println("NY Parsing error XML...");
return "NY Error XML Message";
}
}
package com.javacodegeeks.patterns.abstractfactorypattern;
public class NYFeedbackXMLParser implements XMLParser{
@Override
public String parse() {
System.out.println("NY Parsing feedback XML...");
return "NY Feedback XML Message";
}
}
package com.javacodegeeks.patterns.abstractfactorypattern;
public class NYOrderXMLParser implements XMLParser{
@Override
public String parse() {
System.out.println("NY Parsing order XML...");
return "NY Order XML Message";
}
}
package com.javacodegeeks.patterns.abstractfactorypattern;
public class NYResponseXMLParser implements XMLParser{
@Override
public String parse() {
System.out.println("NY Parsing response XML...");
return "NY Response XML Message";
}
}
package com.javacodegeeks.patterns.abstractfactorypattern;
public class TWErrorXMLParser implements XMLParser{
@Override
public String parse() {
System.out.println("TW Parsing error XML...");
return "TW Error XML Message";
}
}
package com.javacodegeeks.patterns.abstractfactorypattern;
public class TWFeedbackXMLParser implements XMLParser{
@Override
public String parse() {
System.out.println("TW Parsing feedback XML...");
return "TW Feedback XML Message";
}
}
package com.javacodegeeks.patterns.abstractfactorypattern;
public class TWOrderXMLParser implements XMLParser{
@Override
public String parse() {
System.out.println("TW Parsing order XML...");
return "TW Order XML Message";
}
}
package com.javacodegeeks.patterns.abstractfactorypattern;
public class TWResponseXMLParser implements XMLParser{
@Override
public 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