设计模式-工厂模式

设计模式-工厂模式写在前面 Hello 我是易元 本文主要详细介绍工厂模式的分类 定义及其在实际场景中的使用 若内容有误 请大家留言指正 前言工厂模式 Factory Pattern 是一种创建型设计模式 提供了一种创建对象的方式 而无需指定具体的类

大家好,欢迎来到IT知识分享网。

写在前面

Hello,我是易元,本文主要详细介绍工厂模式的分类、定义及其在实际场景中的使用,若内容有误,请大家留言指正!!

前言

工厂模式(Factory Pattern)是一种创建型设计模式,提供了一种创建对象的方式,而无需指定具体的类。

工厂模式的核心思想是将对象的创建过程进行封装,使得客户端代码与具体类的实现解耦

创建型设计模式共有五种:工厂方法模式抽象工厂模式建造者模式原型模式单例模式

分类

工厂模式主要分为三种:

简单工厂模式(Simple Factory)

工厂方法模式(Factory Method)

抽象工厂模式(Abstract Factory)

简单工厂模式

定义

简单工厂模式通过一个工厂类来创建不同类型的对象,客户端只需要传递参数即可获取所需对象。

工厂方法模式中定义了一个抽象工厂类,并且定义了创建产品对象的公共接口,返回抽象产品对象,抽象工厂子类实现了抽象接口,返回具体产品对象。

使用场景

  1. 对象的创建逻辑简单。
  2. 客户端不需要关心对象的创建细节。

简单示例

产品接口

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 } } 

工厂方法模式

定义

工厂方法模式定义了一个创建对象的接口,但由子类决定实例化具体的类,将对象的创建延迟到子类

将对象的创建延迟到子类解释:工厂方法模式中定义了一个抽象工厂类,并且定义了创建产品对象的公共接口,返回抽象产品对象,抽象工厂子类实现了抽象接口,返回具体产品对象。

使用场景

  1. 对象的创建逻辑复杂,需要根据不同条件创建不同对象。
  2. 需要扩展时,可以通过新增子类来实现。

简单示例

产品接口

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的具体实现(自定义创建的实现类)。

ClassPathXmlApplicationContextApplicationContext的实现类ApplicationContextBeanFactory的子接口,对BeanFactory进行了扩展,例如:国际化、事件发布等

public interface ApplicationContext extends Bean>Factory {
String getApplicationName(); // 获取应用名称
String getDisplayName(); // 获取显示名称
long getStartupDate(); // 获取启动时间
void publishEvent(ApplicationEvent event); >// 发布事件
}

抽象工厂模式

定义

抽象工厂模式提供了一个创建一系列相关或相互依赖对象的接口,无需指定它们的具体类。

使用场景

  1. 需要创建一组相关或依赖的对象
  2. 系统中有多个产品族,且客户端只使用其中某一族产品。

简单示例

产品接口

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

DefaultSqlSessionFactorySqlSessionFactory 的具体实现类,负责创建 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

DefaultSqlSessionSqlSession 的具体实现类,负责执行 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(); } } ... } 

长话短说

  1. 简单工厂模式:一个工厂类负责创建所有产品。
  2. 工厂方法模式:每个产品对应一个工厂类。
  3. 抽象工厂模式:每个工厂类负责创建一组相关产品。

何时可以使用?

  1. 对象的创建逻辑复杂
  • 若对象的创建过程涉及到复杂的初始化逻辑(如 配置加载,依赖注入等等),可以使用工厂模式将创建的逻辑封装起来以便后期维护。
  1. 需要支持多种实现
  • 若系统需要支持多种实现(如多种支付方式、多数据库类型等),可以使用工厂模式动态的创建对象。
  1. 需要解耦客户端与具体实现
  • 若客户端代码需要与具体实现进行解耦,可以使用工厂模式隐藏具体实现细节。
  1. 需要集中管理对象的创建
  • 若对象的创建逻辑分散在多个地方,可以使用工厂模式将创建的逻辑集中管理。
  1. 需要动态扩展
  • 若在开发中预见可能存在新的产品类型,可以预先使用工厂模式以便当新的产品出现时动态的扩展。

如何使用?四步走!

  1. 定义产品接口
  • 定义产品的通用接口或抽象类。
  1. 实现具体产品
  • 实现产品接口,定义具体产品的行为。
  1. 定义工厂接口
  • 定义工厂接口,在其中声明产品的创建方法。
  1. 实现具体工厂
  • 实现工厂接口,创建具体产品。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/170693.html

(0)
上一篇 2025-02-19 13:05
下一篇 2025-02-19 13:10

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信