一.介绍
抽象工厂模式(Abstract Factory Pattern)属于创建型模式,它提供了一种创建对象的最佳方式。在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类,每个生成的工厂都能按照工厂模式提供对象。工厂方法模式针对产品等级,而抽象工厂模式针对产品族
二.比较抽象工厂模式与工厂方法模式
工厂方法模式可以参考我写的这篇一起走进工厂方法模式
工厂方法模式中一个产品对应一个工厂类,而在抽象工厂模式中,一个产品族对应一个工厂类
三.UML类图
如果从同一产品等级层面看,我们只关注上半部分的DataBase与Connection,就能看到工厂方法模式的身影
四.具体代码
interface DataBase{
Connection getConnection();
Command getCommand();
}
interface Connection{
void connect();
void close();
}
interface Command{
void prepare();
void exec();
}
class MysqlDataBase implements DataBase{
@Override
public Connection getConnection() {
return new MysqlConnection();
}
@Override
public Command getCommand() {
return new MysqlCommand();
}
}
class MysqlConnection implements Connection{
@Override
public void connect() {
System.out.println("mysql connect");
}
@Override
public void close() {
System.out.println("mysql close");
}
}
class MysqlCommand implements Command{
@Override
public void prepare() {
System.out.println("mysql prepare");
}
@Override
public void exec() {
System.out.println("mysql exec");
}
}
class OracleDataBase implements DataBase{
@Override
public Connection getConnection() {
return new OracleConnection();
}
@Override
public Command getCommand() {
return new OracleCommand();
}
}
class OracleConnection implements Connection{
@Override
public void connect() {
System.out.println("oracle connect");
}
@Override
public void close() {
System.out.println("oracle close");
}
}
class OracleCommand implements Command{
@Override
public void prepare() {
System.out.println("oracle prepare");
}
@Override
public void exec() {
System.out.println("oracle exec");
}
}
五.意图及应用场景
抽象工厂模式的意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。参照下图,DataBase、Connection、Command三个接口无需等待具体的实现类,也可以完成业务的开发,后续如果出现了具体的实现类,只需要将父类的引用指向子类对象DataBase dataBase = new MysqlDataBase()
DataBase dataBase = null;
Connection connection = dataBase.getConnection();
Command command = dataBase.getCommand();
connection.connect();
command.prepare();
command.exec();
connection.close();
应用场景:
1.程序需要处理不同系列的相关产品,但是不希望它依赖于这些产品的具体类
2.系统中有多个产品族,但每次只使用其中的某一族产品
六.优缺点
- 优点
- 符合开闭原则(新增一个类型的数据库不需要改动原有逻辑)
- 符合单一职责原则(Mysql的实现只关注Mysql,Oracle的实现只关注Oracle)
- 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象(不可能从Mysql数据库中拿到Oracle的连接)
- 缺点
- 当产品族中需要增加一个新的产品时,所有工厂类都需要进行修改/适配
七.在JDK中的应用
1.java.sql.Driver
2.java.sql.Connection