Java设计模式-Abstract Factory抽象工厂模式
概念
抽象工厂模式,是对工厂模式的进一步推广,对方法工厂模式进行抽象。就是围绕一个超级工厂去创建其他的工厂,和工厂模式一样,是属于一种创建型的设计模式,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
为什么要使用抽象工厂模式
存在即合理,每一种设计模式都是针对某个问题提供的一种解决方案,抽象工厂模式的意图就是提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。主要就在于相互依赖,用抽象工厂里的专业术语来说,就是产品族和产品等级之间的一个相互依赖关系,就拿之前的工厂模式的那个例子来说:
//以获取链接对象为例
//创建统一接口
public interface DataBaseConnect {
Object backConnection();
}
//Mysql连接类
public class MySQLConnect implements DataBaseConnect {
@Override
public Object backConnection() {
//省略连接代码
return "返回mysql连接对象";
}
}
//SQL server连接类
public class SqlServerConnect implements DataBaseConnect {
@Override
public Object backConnection() {
//省略连接细节
return "返回SqlServer连接对象";
}
}
//工厂类
public class ConnectFactory {
public static DataBaseConnect getConnect(String type){
if (type==null||type.equals("")){
throw new RuntimeException("连接类型不能为空");
}
if(type.equals("MYSQL")){
return new MySQLConnect();
}else{
return new SqlServerConnect();
}
}
}
//测试类
public static void main(String[] args) {
DataBaseConnect connect=ConnectFactory.getConnect("MYSQL");
System.out.println( connect.backConnection());
}
- 产品族指位于不同产品等级结构中,功能相关联的产品组成的家族,mysql的驱动+mysql的连接对象+mysql执行对象是一个产品族,SQL server驱动+SQL server的连接+SQL Server执行对象是一个产品族
- 产品等级就是不同的数据库都共同拥有的一些行为或是属性,比如:获取连接对象、获取数据库驱动、获取失sql执行对象是两种数据库都有的相同结构的产品,这就是几个产品等级
- 在上面这个例子里,因为是只有一个行为,就是获取连接对象,那么如果我再添加获取数据库驱动和关闭连接的行为,此时就会需要三个工厂来维护三种不同的产品等级,调用者在使用的时候,就要通过三个工厂去获取数据库驱动、连接对象、sql执行对象的方法,然后自己进行组装,关注的东西比较多,那么很有可能会出现使用mysql数据库驱动去获取SQL server数据库连接,很显然这就是不正确的操作。那么这个时候就可以引进抽象工厂模式,用来处理具有相同(或者相似)等级结构中的多个产品族中的产品对象的创建问题。也就是说工厂模式针对的是一个产品等级结构,那么抽象工厂模式针对的就是多个产品等级结构。
具体实现
在上面工厂模式的基础上进行改动
//以获取不同数据库驱动、连接为例
//创建获取驱动接口
public interface DataBaseDrive {
public Object getDrive();
}
//获取MySQL驱动
public class MySqlDrive implements DataBaseDrive {
@Override
public Object getDrive() {
return "返回mysql数据库连接";
}
}
//获取SQlserver驱动
public class SqlServerDrive implements DataBaseDrive {
@Override
public Object getDrive() {
return "返回Sqlserver驱动";
}
}
//创建获取连接接口
public interface DataBaseConnect {
Object backConnection();
}
//Mysql连接类
public class MySQLConnect implements DataBaseConnect {
@Override
public Object backConnection() {
//省略连接代码
return "返回mysql连接对象";
}
}
//SQL server连接类
public class SqlServerConnect implements DataBaseConnect {
@Override
public Object backConnection() {
//省略连接细节
return "返回SqlServer连接对象";
}
}
//创建抽象工厂类
public abstract class DataBaseAbstractFactory {
public abstract DataBaseConnect getConnect();
public abstract DataBaseDrive getDrive();
}
//mysql抽象工厂
public class MySqlFactory extends DataBaseAbstractFactory {
@Override
public DataBaseConnect getConnect() {
return new MySQLConnect();
}
@Override
public DataBaseDrive getDrive() {
return new MySqlDrive();
}
}
//sqlserver抽象工厂
public class SqlServerFactory extends DataBaseAbstractFactory {
@Override
public DataBaseConnect getConnect() {
return new SqlServerConnect();
}
@Override
public DataBaseDrive getDrive() {
return new SqlServerDrive();
}
}
//工厂创造器,通过同一个创造器去获取不同工厂得到不同产品对象
public class FactoryProducer {
public static DataBaseAbstractFactory getFactory(String type){
if (type==null||type.equals("")){
throw new RuntimeException("类型不能为空");
}
if(type.equals("SQLSERVER")){
return new SqlServerFactory();
}
return new MySqlFactory();
}
}
//测试类
public static void main(String[] args) {
DataBaseAbstractFactory dataBaseAbstractFactory=FactoryProducer.getFactory("SQLSERVER");
DataBaseDrive dataBaseDriver=dataBaseAbstractFactory.getDrive();
System.out.println(dataBaseDriver.getDrive());
DataBaseConnect dataBaseConnect=dataBaseAbstractFactory.getConnect();
System.out.println(dataBaseConnect.backConnection());
}
抽象工厂模式的优缺点
优点:
- 将接口和实现分离开来,调用者在创建对象的时候,不知道自己具体实现的是谁,只是面向的产品接口编程,从而实现解耦
- 产品间的切换也变简单了,不需要再从多个产品等级的工厂中去获取,而是通过一个统一的入口,切换一个抽象工厂对象即可
缺点:
- 不利于扩展,在某个产品组中添加一个新的产品,需要改动抽象工厂类,从而导致其所有的实现类都要进行修改。