抽象工厂:
定义与类型
- 定义:抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口
- 无需制定它们具体的类
- 类型:创建型
使用场景 - 客户端不依赖于产品类实例如何被创建、实现等细节
- 强调一系列相关的产品对象(属于统一产品族)一起使用创建对象需要大量重复的代码
- 提供一个产品类的库,所以的产品以同样的接口出现,从而使客户端不依赖具体实现
优点 - 具体产品在应用层代码隔离,无须关系创建细节
- 将一个系列的产品统一到一起创建
缺点 - 规定了所有可能被创建的产品集合,产品族扩展新的产品困难,需要修改抽象工厂的接口
- 增加了系统的抽象性和理解难度
UML关系图:

抽象工厂主要分为4类:
-
AbstractFactory
:抽象工厂角色,它声明了一组用于创建一种产品的方法,每一个方法对应一种产品,如上述类图中的AbstractFactory就定义了两个方法,分别创建产品A和产品B -
ConcreteFactory
:具体工厂角色,它实现了在抽象工厂中定义的创建产品的方法,生产一组具体产品,这饿产品构件成了一个产品种类,每一个产品都位于某个产品等级结构中,如上述类图中的ConcreteFactoryA和ConcreteFactoryB -
AbstractProduct
:抽象产品角色,为每种产品声明接口,如图中AbstractProductA、AbstractProductB -
ConcreteProduct
:具体产品角色,定义了工厂生产的具体产品对象,实现抽象产品接口声明的业务方法,如图中ConcreteProductA1、ConcreteProductA2、ConcreteProductB1、ConcreteProductB2
模式代码
- AbstractProduct:
public abstract class Video {
public abstract void produce();
}
- ConcreteProduct:
public class PythonVideo extends Video {
@Override
public void produce() {
System.out.println("Python课程视频");
}
}
public class JavaVideo extends Video {
@Override
public void produce() {
System.out.println("录制Java课程视频");
}
}
- AbstractFactory:
public interface CourseFactory {
Video getVideo();
Article getArticle();
}
- ConcreteFactory:
public class JavaCourseFactory implements CourseFactory {
@Override
public Video getVideo() {
return new JavaVideo();
}
@Override
public Article getArticle() {
return new JavaArticle();
}
}
public class PythonCourseFactory implements CourseFactory {
@Override
public Video getVideo() {
return new PythonVideo();
}
@Override
public Article getArticle() {
return new PythonArticle();
}
}
源码中的使用:
- java.sql下的Statement、CallableStatement(抽象产品):
public interface Statement extends Wrapper, AutoCloseable {
'省略代码'
}
public interface CallableStatement extends PreparedStatement {
'省略代码'
}
- com.mysql.jdb下的StatementImpl、CallableStatement(具体产品)
public class StatementImpl implements Statement {
'省略代码'
}
package com.mysql.jdbc;
public class CallableStatement extends PreparedStatement implements java.sql.CallableStatement {
'省略代码'
}
- java.sql下的Connection(抽象工厂):
public interface Connection extends Wrapper, AutoCloseable {
Statement createStatement() throws SQLException;
CallableStatement prepareCall(String sql) throws SQLException;
'省略代码'
- com.mysql.jdbc下的ConnectionImpl(具体工厂):
public class ConnectionImpl extends ConnectionPropertiesImpl implements Connection {
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
this.checkClosed();
StatementImpl stmt = new StatementImpl(this, this.database);
stmt.setResultSetType(resultSetType);
stmt.setResultSetConcurrency(resultSetConcurrency);
return stmt;
}
public java.sql.CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
if (this.versionMeetsMinimum(5, 0, 0)) {
CallableStatement cStmt = null;
if (!this.getCacheCallableStatements()) {
cStmt = this.parseCallableStatement(sql);
} else {
LRUCache var5 = this.parsedCallableStatementCache;
synchronized(this.parsedCallableStatementCache) {
ConnectionImpl.CompoundCacheKey key = new ConnectionImpl.CompoundCacheKey(this.getCatalog(), sql);
CallableStatementParamInfo cachedParamInfo = (CallableStatementParamInfo)this.parsedCallableStatementCache.get(key);
if (cachedParamInfo != null) {
cStmt = CallableStatement.getInstance(this, cachedParamInfo);
} else {
cStmt = this.parseCallableStatement(sql);
cachedParamInfo = cStmt.paramInfo;
this.parsedCallableStatementCache.put(key, cachedParamInfo);
}
}
}
cStmt.setResultSetType(resultSetType);
cStmt.setResultSetConcurrency(resultSetConcurrency);
return cStmt;
} else {
throw SQLError.createSQLException("Callable statements not supported.", "S1C00");
}
}
}
抽象工厂在实际的开发中运用并不多,主要是在开发工程中很少会出现多个产品种类的情况,大部分情况使用工程模式即可解决
网友评论