大家好,欢迎来到IT知识分享网。
写在前面
❝
Hello,我是易元,本文主要详细介绍工厂模式的分类、定义及其在实际场景中的使用,若内容有误,请大家留言指正!!
前言
工厂模式(Factory Pattern)是一种创建型设计模式,提供了一种创建对象的方式,而无需指定具体的类。
工厂模式的核心思想是将对象的创建过程进行封装,使得客户端代码与具体类的实现解耦。
❝
创建型设计模式共有五种:工厂方法模式、抽象工厂模式、建造者模式、原型模式、单例模式。
分类
❝
工厂模式主要分为三种:
简单工厂模式(Simple Factory)
工厂方法模式(Factory Method)
抽象工厂模式(Abstract Factory)
简单工厂模式
定义
简单工厂模式通过一个工厂类来创建不同类型的对象,客户端只需要传递参数即可获取所需对象。
工厂方法模式中定义了一个抽象工厂类,并且定义了创建产品对象的公共接口,返回抽象产品对象,抽象工厂子类实现了抽象接口,返回具体产品对象。
使用场景
- 对象的创建逻辑简单。
- 客户端不需要关心对象的创建细节。
简单示例
产品接口
public interface Product { void use(); }
具体产品
public class ProductA implements Product { @Override public void use() { System.out.println("使用产品 A"); } }
public class ProductB implements Product { @Override public void use() { System.out.println("使用产品 B"); } }
简单工厂类
public class SimpleFactory { public static Product createProduct(String type) { if ("A".equals(type)) { return new ProductA(); } else if ("B".equals(type)) { return new ProductB(); } throw new IllegalArgumentException("未知产品类型!"); } }
客户端代码
public class Client { public static void main(String[] args) { Product productA = SimpleFactory.createProduct("A"); productA.use(); // 输出: 使用产品 A Product productB = SimpleFactory.createProduct("B"); productB.use(); // 输出: 使用产品 B } }
工厂方法模式
定义
工厂方法模式定义了一个创建对象的接口,但由子类决定实例化具体的类,将对象的创建延迟到子类。
❝
将对象的创建延迟到子类解释:工厂方法模式中定义了一个抽象工厂类,并且定义了创建产品对象的公共接口,返回抽象产品对象,抽象工厂子类实现了抽象接口,返回具体产品对象。
使用场景
- 对象的创建逻辑复杂,需要根据不同条件创建不同对象。
- 需要扩展时,可以通过新增子类来实现。
简单示例
产品接口
public interface Product { void use(); }
具体产品
public class ProductA implements Product { @Override public void use() { System.out.println("使用产品 A"); } } public class ProductB implements Product { @Override public void use() { System.out.println("使用产品 B"); } }
工厂接口
public interface Factory { Product createProduct(); }
具体工厂
public class FactoryA implements Factory { @Override public Product createProduct() { return new ProductA(); } } public class FactoryB implements Factory { @Override public Product createProduct() { return new ProductB(); } }
客户端代码
public class Client { public static void main(String[] args) { Factory factoryA = new FactoryA(); // 由子类创建产品对象 Product productA = factoryA.createProduct(); productA.use(); // 输出: 使用产品 A Factory factoryB = new FactoryB(); Product productB = factoryB.createProduct(); productB.use(); // 输出: 使用产品 B } }
实际使用案例
在 Spring Framework 中的使用
工厂接口BeanFactory
Spring中最基础的工厂接口,定义了获取Bean的方法。
public interface BeanFactory { Object getBean(String name) throws BeansException; // 通过名称获取 Bean <T> T getBean(String name, Class<T> requiredType) throws BeansException; // 通过名称和类型获取 Bean <T> T getBean(Class<T> requiredType) throws BeansException; // 通过类型获取 Bean boolean containsBean(String name); // 检查是否包含指定名称的 Bean }
具体工厂实现 ClassPathXmlApplicationContext
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); MyBean myBean = context.getBean(MyBean.class);
产品接口可以理解为Spring管理的Bean的通用接口(自定义创建的接口类),而具体产品则是这些Bean的具体实现(自定义创建的实现类)。
❝
ClassPathXmlApplicationContext为ApplicationContext的实现类ApplicationContext是BeanFactory的子接口,对BeanFactory进行了扩展,例如:国际化、事件发布等
public interface ApplicationContext extends Bean>Factory {
String getApplicationName(); // 获取应用名称
String getDisplayName(); // 获取显示名称
long getStartupDate(); // 获取启动时间
void publishEvent(ApplicationEvent event); >// 发布事件
}
抽象工厂模式
定义
抽象工厂模式提供了一个创建一系列相关或相互依赖对象的接口,无需指定它们的具体类。
使用场景
- 需要创建一组相关或依赖的对象
- 系统中有多个产品族,且客户端只使用其中某一族产品。
简单示例
产品接口
public interface Product { void use(); }
具体产品
public class ProductA1 implements Product { @Override public void use() { System.out.println("使用产品 A1"); } } public class ProductA2 implements Product { @Override public void use() { System.out.println("使用产品 A2"); } } public class ProductB1 implements Product { @Override public void use() { System.out.println("使用产品 B1"); } } public class ProductB2 implements Product { @Override public void use() { System.out.println("使用产品 B2"); } }
抽象工厂接口
public interface AbstractFactory { Product createProduct1(); Product createProduct2(); }
具体工厂
// A 类型产品 public class FactoryA implements AbstractFactory { @Override public Product createProduct1() { return new ProductA1(); } @Override public Product createProduct2() { return new ProductA2(); } } // B 类型产品 public class FactoryB implements AbstractFactory { @Override public Product createProduct1() { return new ProductB1(); } @Override public Product createProduct2() { return new ProductB2(); } }
客户端代码
public class Client { public static void main(String[] args) { AbstractFactory factoryA = new FactoryA(); Product productA1 = factoryA.createProduct1(); Product productA2 = factoryA.createProduct2(); productA1.use(); // 输出: 使用产品 A1 productA2.use(); // 输出: 使用产品 A2 AbstractFactory factoryB = new FactoryB(); Product productB1 = factoryB.createProduct1(); Product productB2 = factoryB.createProduct2(); productB1.use(); // 输出: 使用产品 B1 productB2.use(); // 输出: 使用产品 B2 } }
实际使用案例
在 MyBatis 中的使用
抽象工厂SqlSessionFactory
SqlSessionFactory 是 MyBatis 的核心接口,定义了创建 SqlSession 的方法.
public interface SqlSessionFactory { SqlSession openSession(); // 创建 SqlSession SqlSession openSession(boolean autoCommit); // 创建 SqlSession,指定是否自动提交 SqlSession openSession(Connection connection); // 创建 SqlSession,使用指定的数据库连接 Configuration getConfiguration(); // 获取配置信息 }
具体工厂DefaultSqlSessionFactory
DefaultSqlSessionFactory 是 SqlSessionFactory 的具体实现类,负责创建 SqlSession 对象。
public class DefaultSqlSessionFactory implements SqlSessionFactory { private final Configuration configuration; public DefaultSqlSessionFactory(Configuration configuration) { this.configuration = configuration; } @Override public SqlSession openSession() { return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false); } @Override public SqlSession openSession(boolean autoCommit) { return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit); } @Override public SqlSession openSession(Connection connection) { return openSessionFromConnection(configuration.getDefaultExecutorType(), connection); } @Override public Configuration getConfiguration() { return configuration; } // 创建 SqlSession 的具体逻辑 private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { } // 创建 SqlSession 的具体逻辑 private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) { } }
抽象产品SqlSession
SqlSession 是 MyBatis 的核心接口,定义了执行 SQL 命令、获取映射器等。
public interface SqlSession extends Closeable { <T> T selectOne(String statement); // 查询单条记录 <T> T selectOne(String statement, Object parameter); // 查询单条记录,带参数 <E> List<E> selectList(String statement); // 查询多条记录 <E> List<E> selectList(String statement, Object parameter); // 查询多条记录,带参数 int insert(String statement); // 插入记录 int insert(String statement, Object parameter); // 插入记录,带参数 int update(String statement); // 更新记录 int update(String statement, Object parameter); // 更新记录,带参数 int delete(String statement); // 删除记录 int delete(String statement, Object parameter); // 删除记录,带参数 void commit(); // 提交事务 void rollback(); // 回滚事务 <T> T getMapper(Class<T> type); // 获取映射器 Connection getConnection(); // 获取数据库连接 }
具体产品DefaultSqlSession
DefaultSqlSession 是 SqlSession 的具体实现类,负责执行 SQL 命令、管理事务等。
public class DefaultSqlSession implements SqlSession { private final Configuration configuration; private final Executor executor; private final boolean autoCommit; public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) { this.configuration = configuration; this.executor = executor; this.autoCommit = autoCommit; } @Override public <T> T selectOne(String statement) { return selectOne(statement, null); } @Override public <T> T selectOne(String statement, Object parameter) { List<T> list = selectList(statement, parameter); if (list.size() == 1) { return list.get(0); } else if (list.size() > 1) { throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size()); } else { return null; } } @Override public <E> List<E> selectList(String statement) { return selectList(statement, null); } @Override public <E> List<E> selectList(String statement, Object parameter) { try { MappedStatement ms = configuration.getMappedStatement(statement); return executor.query(ms, parameter, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER); } catch (Exception e) { throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } ... }
长话短说
- 简单工厂模式:一个工厂类负责创建所有产品。
- 工厂方法模式:每个产品对应一个工厂类。
- 抽象工厂模式:每个工厂类负责创建一组相关产品。
何时可以使用?
- 对象的创建逻辑复杂
- 若对象的创建过程涉及到复杂的初始化逻辑(如 配置加载,依赖注入等等),可以使用工厂模式将创建的逻辑封装起来以便后期维护。
- 需要支持多种实现
- 若系统需要支持多种实现(如多种支付方式、多数据库类型等),可以使用工厂模式动态的创建对象。
- 需要解耦客户端与具体实现
- 若客户端代码需要与具体实现进行解耦,可以使用工厂模式隐藏具体实现细节。
- 需要集中管理对象的创建
- 若对象的创建逻辑分散在多个地方,可以使用工厂模式将创建的逻辑集中管理。
- 需要动态扩展
- 若在开发中预见可能存在新的产品类型,可以预先使用工厂模式以便当新的产品出现时动态的扩展。
如何使用?四步走!
- 定义产品接口
- 定义产品的通用接口或抽象类。
- 实现具体产品
- 实现产品接口,定义具体产品的行为。
- 定义工厂接口
- 定义工厂接口,在其中声明产品的创建方法。
- 实现具体工厂
- 实现工厂接口,创建具体产品。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/170693.html