一、模式定义
抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于创建型模式。
抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形态。
抽象工厂模式与工厂方法模式最大的区别在于:
-
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。 -
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例,也就是创建的是一个产品线下的多个产品。
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个;
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个;
抽象工厂更像工厂,可以生产不同类的产品。而工厂方法则更像是工厂的一种产品生产线,生产同类不同规格的产品。
二、模式动机
请先阅读《Java GoF 23种设计模式-创建型模式-工厂方法模式(Factory Method Pattern)》
假设你正在开发一款家具商店模拟器。 你的代码中包括一些类, 用于表示:
1、一系列相关产品, 例如 椅子Chair 、沙发Sofa、咖啡桌Coffee Table。
2、系列产品的不同变体,你可以使用不同风格生成椅子 、 沙发、咖啡桌(现代Mordern 、维多利亚Victorian 、 装饰风艺术Art Deco等风格) 。
在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法。但是有时候我们需要一个工厂可以提供多个产品对象,而不是单一的产品对象。
工厂方法创建 “一种” 产品,他的重点在于"怎么创建";
抽象工厂需要创建一系列产品,重点在于"创建哪些"产品上,以及这些产品如何组合;
三、模式结构
四、代码实现
4.1 Sender产品及其实现
Sender.java
package com.design.demo.abstractfactory;
/**
* @author administrator
* @date 2020-05-16 14:21
*/
public interface Sender {
/**
* 信息发送
*/
public void send(String message);
}
SmsSender.java
package com.design.demo.abstractfactory;
/**
* 短信发送信息实现类
* @author administrator
* @date 2020-05-16 14:22
*/
public class SmsSender implements Sender {
@Override
public void send(String message) {
System.out.println("通过短信发送信息:" + message);
}
}
EmailSender.java
package com.design.demo.abstractfactory;
/**
* 邮箱发送信息实现类
* @author administrator
* @date 2020-05-16 14:22
*/
public class EmailSender implements Sender {
@Override
public void send(String message) {
System.out.println("通过邮件发送信息:" + message);
}
}
4.2 Logger产品及其实现
Logger.java
package com.design.demo.abstractfactory;
/**
* @author administrator
* @date 2020-05-16 17:04
*/
public interface Logger {
/**
* 记录日志
*/
public void writeLog(String logStr);
}
DatabaseLogger.java
package com.design.demo.abstractfactory;
/**
* @author administrator
* @date 2020-05-16 17:05
*/
public class DatabaseLogger implements Logger {
@Override
public void writeLog(String logStr) {
System.out.println("写日志到数据库表中,日志消息是:" + logStr);
}
}
DiskFileLogger.java
package com.design.demo.abstractfactory;
/**
* @author administrator
* @date 2020-05-16 17:05
*/
public class DiskFileLogger implements Logger {
@Override
public void writeLog(String logStr) {
System.out.println("写日志到磁盘文件中,日志消息是:" + logStr);
}
}
4.3 工厂类及其实现
Factory.java
package com.design.demo.abstractfactory;
/**
* 抽象工厂
* @author administrator
* @date 2020-05-16 15:44
*/
public interface Factory {
//创造Sender具体对象
public Sender newSender();
//创造Logger具体对象
public Logger newLogger();
}
EmailSenderDatabaseLoggerFactory.java
package com.design.demo.abstractfactory;
/**
* @author administrator
* @date 2020-05-16 16:16
*/
public class EmailSenderDatabaseLoggerFactory implements Factory {
@Override
public Sender newSender() {
return new EmailSender();
}
@Override
public Logger newLogger() {
return new DatabaseLogger();
}
}
SmsSenderDiskFileLoggerFactory.java
package com.design.demo.abstractfactory;
/**
* @author administrator
* @date 2020-05-16 16:16
*/
public class SmsSenderDiskFileLoggerFactory implements Factory {
@Override
public Sender newSender() {
return new SmsSender();
}
@Override
public Logger newLogger() {
return new DiskFileLogger();
}
}
4.4 测试及运行结果
package com.design.demo.abstractfactory;
/**
* @author administrator
* @date 2020-05-16 16:18
*/
public class ClientTest {
public static void emailMethod() {
//发送邮件和记录数据库日志
Factory edFactory = new EmailSenderDatabaseLoggerFactory();
Sender edSender = edFactory.newSender();
edSender.send("message abc ...");
Logger edLogger = edFactory.newLogger();
edLogger.writeLog("log abc ...");
}
public static void smsMethod() {
//发送短信和记录磁盘文件日志
Factory smsdFactory = new SmsSenderDiskFileLoggerFactory();
Sender smsSender = smsdFactory.newSender();
smsSender.send("message abc ...");
Logger smsdLogger = smsdFactory.newLogger();
smsdLogger.writeLog("log abc ...");
}
public static void main(String[] args) {
emailMethod();
smsMethod();
}
}