一、定义
抽象工厂模式(Abstract Factory Pattern):创新型模式之一,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
二、UML类图
三、角色职责
- 抽象产品(Product):它是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的公共父类。
- 具体产品(Concrete Product):它实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,具体工厂和具体产品之间一一对应。
- 抽象工厂(Factory):在抽象工厂类中声明了工厂方法(Factory Method),用于返回一个产品。抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口。
- 具体工厂(Concrete Factory):它是抽象工厂类的子类,实现了在抽象工厂中声明的工厂方法,并可由客户端调用,返回一个具体产品类的实例。
四、代码实现
前言:
抽象篮球接口(抽象产品类 abstract Product)
public interface BasketBall {
void shot();
}
阿迪达斯篮球(具体产品类 Concreate Product)
public class AdidasBasketBall implements BasketBall {
@Override
public void shot() {
System.out.println("使用阿迪达斯篮球投篮");
}
}
耐克篮球(具体产品类 Concreate Product)
public class NikeBasketBall implements BasketBall {
@Override
public void shot() {
System.out.println("使用耐克篮球投篮");
}
}
抽象足球接口(抽象产品类 abstract Product)
public interface FootBall {
void goal();
}
阿迪达斯足球(具体产品类 Concreate Product)
public class AdidasFootBall implements FootBall {
@Override
public void goal() {
System.out.println("使用阿迪达斯足球射门");
}
}
耐克足球(具体产品类 Concreate Product)
public class NikeFootBall implements FootBall {
@Override
public void goal() {
System.out.println("使用耐克足球射门");
}
}
抽象工厂接口(抽象工厂类 Factory)
public interface Factory {
BasketBall makeBasketBall();
FootBall makeFootBall();
}
阿迪达斯工厂(具体工厂类 Concreate Factory)
public class AdidasFactory implements Factory {
@Override
public BasketBall makeBasketBall() {
return new AdidasBasketBall();
}
@Override
public FootBall makeFootBall() {
return new AdidasFootBall();
}
}
耐克工厂(具体工厂类 Concreate Factory)
public class NikeFactory implements Factory {
@Override
public BasketBall makeBasketBall() {
return new NikeBasketBall();
}
@Override
public FootBall makeFootBall() {
return new NikeFootBall();
}
}
测试类
public class AbstractFactoryTest {
public static void main(String[] args) {
Factory adidasFactory = new AdidasFactory();
// 使用阿迪达斯篮球投篮
adidasFactory.makeBasketBall().shot();
// 使用阿迪达斯足球射门
adidasFactory.makeFootBall().goal();
Factory nikeFactory = new NikeFactory();
// 使用耐克篮球投篮
nikeFactory.makeBasketBall().shot();
// 使用耐克足球射门
nikeFactory.makeFootBall().goal();
}
}
五、源码分析
在MyBatis中,就有一个非常典型的抽象工厂模式。
其中SqlSession是Mybatis的主要Java接口
他有一个默认的实现类:DefaultSqlSession
SqlSessionFactory是用于从数据源或数据库连接中创建SqlSession的抽象工厂接口
SqlSessionFactory也有一个默认的实现类:DefaultSqlSessionFactory
我们点开openSessionFromDataSource方法,从数据源中打开Session
实际返回的是DefaultSqlSession
从上面的源码可以得知,DefaultSqlSession是实现了SqlSession抽象接口的具体产品,DefaultSqlSessionFactory是实现了SqlSessionFactory抽象接口的具体工厂,并且用来生产DefaultSqlSession,这就是典型的抽象工厂模式的实现。
六、优缺点分析
优点:
- 具体产品在应用层的代码隔离,无需关系创建的细节。
- 将一个系列的产品统一到一起创建。
缺点:
- 增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码。
七、适用场景
当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。
八、总结
一个继承体系中,如果存在着多个等级结构(即存在着多个抽象类),并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式。假如各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行创建,则更合适一点。