设计模式之抽象工厂模式

抽象工厂模式是一种创建型设计模式,用于创建一系列相关或依赖的对象,无需指定它们的具体类。它提供了创建产品族的接口,每个具体工厂生产一个产品族中的多个产品。文章通过汽车品牌工厂的例子展示了模式的实现,并提到了在JDBC中Connection接口作为抽象工厂,创建Statement、PreparedStatement和CallableStatement等抽象产品的实例。
摘要由CSDN通过智能技术生成

什么是抽象工厂模式

    抽象工厂模式提供了一个创建一系列相关或相互依赖对象的接口,而无需指定他们的具体类。该模式属于创建型设计模式。。
    抽象工厂模式为创建一组对象提供了一种解决方案。与工厂方法模式相比,抽象工厂中的具体工厂不只是创建一个产品,而是创建一组产品。
    在抽象工厂模式中,每一个具体工厂都提供了多个工厂方法用于生产多种不同的产品,这些产品组成一个产品组。
    在工厂方法模式中具体工厂只负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法具有唯一性。一般情况下,一个具体工厂只有一个或一组重载的工厂方法。
    抽象工厂模式包含一下几个角色:
        AbstractFactory(抽象工厂):声明了一组用于创建一组产品的方法,每一个方法对应一种产品。
        ConcreteFactory(具体工厂):实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品组。
        AbstractProduct(抽象产品):为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。
        ConcreteProduct(具体产品):定义了具体工厂生产的具体产品的对象,实现抽象产品接口中声明的业务方法。
    在抽象工厂中声明多个工厂方法,用于创建不同类型的产品,抽象工厂可以是接口,也可以是抽象类或具体类(可能有很多初学者认为抽象工厂模式就是定义抽象类,其实不然,这是一个误区!)
    具体工厂实现了抽象工厂,每一个具体的工厂方法可以返回一个特定的产品对象,而同一个具体工厂所创建的产品对象构成了产品组。

抽象工厂模式的优缺点

优点

  1. 抽象工厂模式隔离了具体类的生成,我们可以很容易的切换一个具体工厂。
  2. 当一个产品组中的多个对象设计到一起时,能够保证同时只能使用同一个产品组中的一个对象。
  3. 新增产品组很方便,符合开闭原则。

缺点

  1. 增加新的产品等级结构比较麻烦,需要修改所有的工厂角色,包括抽象工厂类,在所有的工厂类中都需要增加新的产品方法,不符合开闭原则。

  2. 抽象工厂模式的应用场景

  3. 一个系统不应该依赖于产品类如何被创建,组合和表达的细节

  4. 系统中有多个产品组,而每次只使用其中一个

抽象工厂模式案例

/**
 * 创建蔚小理的抽象工厂,分SUV和轿车
 */
public abstract class AbstractCardFactory {
    // 买SUV
    public abstract SUV orderSUV();
    // 买轿车
    public abstract LittleCar orderLittleCar();

}

--------------------------------------------------------------------------------

/**
 * 蔚来车具体工厂
 */
public class NIOCarFactory extends AbstractCardFactory {
    @Override
    public SUV orderSUV() {
        return new NIOSUV();
    }

    @Override
    public LittleCar orderLittleCar() {
        return new NIOLittleCar();
    }
}

/**
 * 理想车具体工厂
 */
public class ONECarFactory extends AbstractCardFactory {

    @Override
    public SUV orderSUV() {
        return new ONESUV();
    }

    @Override
    public LittleCar orderLittleCar() {
        return new ONELittleCar();
    }

}

/**
 * 小鹏车具体工厂
 */
public class XPCarFactory extends AbstractCardFactory {

    @Override
    public SUV orderSUV() {
        return new XPSUV();
    }

    @Override
    public LittleCar orderLittleCar() {
        return new XPLittleCar();
    }
}

--------------------------------------------------------------------------------

/**
 * 轿车抽象产品
 */
public interface LittleCar {

    void buy();

}


/**
 * SUV 抽象产品
 */
public interface SUV {

    void buy();

}
--------------------------------------------------------------------------------

/**
 * 蔚来轿车具体产品
 */
public class NIOLittleCar implements LittleCar {
    @Override
    public void buy() {
        System.out.println("购买蔚来轿车");
    }
}

/**
 * 理想轿车具体产品
 */
public class ONELittleCar implements LittleCar {
    @Override
    public void buy() {
        System.out.println("购买理想轿车");
    }
}

/**
 * 小鹏轿车具体产品
 */
public class XPLittleCar implements LittleCar {
    @Override
    public void buy() {
        System.out.println("购买小鹏轿车");
    }
}

/**
 * 蔚来SUV具体产品
 */
public class NIOSUV implements SUV {

    @Override
    public void buy() {
        System.out.println("购买蔚来SUV");
    }

}

/**
 * 理想SUV具体产品
 */
public class ONESUV implements SUV {
    @Override
    public void buy() {
        System.out.println("购买理想SUV");
    }
}

/**
 * 小鹏SUV具体产品
 */
public class XPSUV implements SUV {

    @Override
    public void buy() {
        System.out.println("购买小鹏SUV");
    }

}

--------------------------------------------------------------------------------

public class Test {

    public static void main(String[] args) {
        // 选择理想
        ONECarFactory oneCarFactory = new ONECarFactory();
        // 购买理想SUV
        oneCarFactory.orderSUV().buy();
        // 选择蔚来
        NIOCarFactory nioCarFactory = new NIOCarFactory();
        // 购买蔚来SUV
        nioCarFactory.orderSUV().buy();

    }
}

在这里插入图片描述

抽象工厂在源码中的应用

JDBC

// Connection 接口是一个经典的抽象工厂
// Statement、PreparedState、CallableStatement 就是 Connection 这个抽象工厂中提供的三个抽象产品

// 抽象工厂
public interface Connection  extends Wrapper, AutoCloseable {
    // 创建sql的执行对象
    Statement createStatement() throws SQLException;
    // 创建支持预编译的sql执行对象
    PreparedStatement prepareStatement(String sql) throws SQLException;
    // 创建支持存储过程的sql执行对象
    CallableStatement prepareCall(String sql) throws SQLException;    
}

// 具体工厂
public class ConnectionImpl implements JdbcConnection, SessionEventListener, Serializable {
    @Override
    public java.sql.Statement createStatement() throws SQLException {
        return createStatement(DEFAULT_RESULT_SET_TYPE, DEFAULT_RESULT_SET_CONCURRENCY);
    }
    
    @Override
    public java.sql.PreparedStatement prepareStatement(String sql) throws SQLException {
        return prepareStatement(sql, DEFAULT_RESULT_SET_TYPE, DEFAULT_RESULT_SET_CONCURRENCY);
    }
    
    @Override
    public java.sql.CallableStatement prepareCall(String sql) throws SQLException {
        return prepareCall(sql, DEFAULT_RESULT_SET_TYPE, DEFAULT_RESULT_SET_CONCURRENCY);
    }
}


// 抽象产品
public interface Statement extends Wrapper, AutoCloseable {
    // 执行查询方法
    ResultSet executeQuery(String sql) throws SQLException;
    // 执行更新方法
    int executeUpdate(String sql) throws SQLException;

}

public interface PreparedStatement extends Statement {
    // 执行查询方法
    ResultSet executeQuery() throws SQLException;
    
    // 执行更新方法
    int executeUpdate() throws SQLException;
}

public interface CallableStatement extends PreparedStatement {
    // 注册存储过程出参
    void registerOutParameter(int parameterIndex, int sqlType) throws SQLException;
}

// 具体工厂
public class StatementImpl implements JdbcStatement {
    @Override
    public java.sql.ResultSet executeQuery(String sql) throws SQLException {
        synchronized (checkClosed().getConnectionMutex()) {
            JdbcConnection locallyScopedConn = this.connection;
    
            this.retrieveGeneratedKeys = false;
    
            checkNullOrEmptyQuery(sql);
    
            resetCancelledState();
    
            implicitlyCloseAllOpenResults();
            
            ......
            return this.results;
        }
    }
    ......
}

public class ClientPreparedStatement extends com.mysql.cj.jdbc.StatementImpl implements JdbcPreparedStatement {
    @Override
    public java.sql.ResultSet executeQuery() throws SQLException {
        synchronized (checkClosed().getConnectionMutex()) {
    
            JdbcConnection locallyScopedConn = this.connection;
    
            checkForDml(((PreparedQuery<?>) this.query).getOriginalSql(), ((PreparedQuery<?>) this.query).getParseInfo().getFirstStmtChar());
    
            this.batchedGeneratedKeys = null;
    
            resetCancelledState();
    
            implicitlyCloseAllOpenResults();
    
            clearWarnings();
            ......
            return this.results;
        }
    }
    ......
}

public class CallableStatement extends ClientPreparedStatement implements java.sql.CallableStatement {
    @Override
    public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException {
        try {
            MysqlType mt = MysqlType.getByJdbcType(sqlType);
            registerOutParameter(parameterIndex, mt);
        } catch (FeatureNotAvailableException nae) {
            throw SQLError.createSQLFeatureNotSupportedException(Messages.getString("Statement.UnsupportedSQLType") + JDBCType.valueOf(sqlType),
                    MysqlErrorNumbers.SQL_STATE_DRIVER_NOT_CAPABLE, getExceptionInterceptor());
        }
    }
    ......
}

在这里插入图片描述


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值