您现在的位置是:首页 >技术交流 >设计模式之工厂模式网站首页技术交流
设计模式之工厂模式
如果你还可以努力、可以付出,就不要轻言停止和放弃。在你停止努力的那一刻之前,一切都还没有什么真正的结果。
简单工厂模式
简单工厂模式(Simple Factory Pattern):由一个工厂类负责创建对象,根据传入的参数或条件决定创建哪种具体对象。客户端只需要与工厂类进行交互,无需直接实例化具体对象。这种模式简单易懂,但扩展性相对较差。
// 抽象产品
interface Product {
void operation();
}
// 具体产品A
class ConcreteProductA implements Product {
@Override
public void operation() {
System.out.println("ConcreteProductA operation");
}
}
// 具体产品B
class ConcreteProductB implements Product {
@Override
public void operation() {
System.out.println("ConcreteProductB operation");
}
}
// 简单工厂
class SimpleFactory {
public Product createProduct(String type) {
if (type.equals("A")) {
return new ConcreteProductA();
} else if (type.equals("B")) {
return new ConcreteProductB();
}
return null;
}
}
// 客户端
public class Client {
public static void main(String[] args) {
SimpleFactory factory = new SimpleFactory();
Product productA = factory.createProduct("A");
Product productB = factory.createProduct("B");
productA.operation(); // 输出: ConcreteProductA operation
productB.operation(); // 输出: ConcreteProductB operation
}
}
解析说明:
- 简单工厂模式通过一个工厂类(SimpleFactory)根据传入的参数创建相应的产品对象。客户端通过调用工厂的方法来获取产品对象,从而实现了对产品创建过程的解耦。
- 在上述示例中,SimpleFactory 根据传入的参数类型创建不同的具体产品对象(ConcreteProductA 和
ConcreteProductB)。客户端只需调用 createProduct
方法,并传入相应的参数(如"A"和"B"),就能获取到相应的产品对象。 - 简单工厂模式适用于创建的产品较少且相对简单的情况,当产品种类增多时,工厂类的代码可能会变得庞大,不易维护。
工厂方法模式
工厂方法模式(Factory Method Pattern):定义一个抽象的工厂接口,让子类来实现工厂接口并负责创建具体对象。每个具体的工厂类负责创建一类具体对象。客户端通过与工厂接口进行交互,无需直接与具体工厂和具体产品类耦合。这种模式具有较好的扩展性,可以根据需求新增具体的工厂和产品类。
// 抽象产品
interface Product {
void operation();
}
// 具体产品A
class ConcreteProductA implements Product {
@Override
public void operation() {
System.out.println("ConcreteProductA operation");
}
}
// 具体产品B
class ConcreteProductB implements Product {
@Override
public void operation() {
System.out.println("ConcreteProductB operation");
}
}
// 抽象工厂
interface Factory {
Product createProduct();
}
// 具体工厂A
class ConcreteFactoryA implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}
// 具体工厂B
class ConcreteFactoryB implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductB();
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Factory factoryA = new ConcreteFactoryA();
Product productA = factoryA.createProduct();
productA.operation(); // 输出: ConcreteProductA operation
Factory factoryB = new ConcreteFactoryB();
Product productB = factoryB.createProduct();
productB.operation(); // 输出: ConcreteProductB operation
}
}
解析说明:
-
工厂方法模式将产品的创建交给具体的工厂类来完成,每个具体工厂类负责创建一种产品。客户端通过调用工厂的方法来获取产品对象,从而实现了对产品创建过程的解耦。
-
在上述示例中,抽象工厂(Factory)定义了创建产品的方法createProduct(),具体工厂(ConcreteFactoryA和 ConcreteFactoryB)实现了这个方法并分别创建了 ConcreteProductA 和 ConcreteProductB
两种具体产品对象。 -
客户端根据需要选择合适的具体工厂,通过调用其 createProduct() 方法来获取相应的产品对象
-
工厂方法模式允许在系统中引入新的产品类型时更加灵活,只需创建对应的具体产品类和具体工厂类即可,而无需修改现有代码。
抽象工厂模式
抽象工厂模式(Abstract Factory Pattern):提供一个抽象的工厂接口,用于创建一系列相关或相互依赖的对象。每个具体的工厂类负责创建一族相关的具体对象。客户端通过与抽象工厂接口进行交互,无需直接与具体工厂和具体产品类耦合。抽象工厂模式可以用于创建一组具有不同产品等级结构的对象,具有较高的灵活性和可扩展性。
// 抽象产品A
interface ProductA {
void operation();
}
// 具体产品A1
class ConcreteProductA1 implements ProductA {
@Override
public void operation() {
System.out.println("ConcreteProductA1 operation");
}
}
// 具体产品A2
class ConcreteProductA2 implements ProductA {
@Override
public void operation() {
System.out.println("ConcreteProductA2 operation");
}
}
// 抽象产品B
interface ProductB {
void operation();
}
// 具体产品B1
class ConcreteProductB1 implements ProductB {
@Override
public void operation() {
System.out.println("ConcreteProductB1 operation");
}
}
// 具体产品B2
class ConcreteProductB2 implements ProductB {
@Override
public void operation() {
System.out.println("ConcreteProductB2 operation");
}
}
// 抽象工厂
interface AbstractFactory {
ProductA createProductA();
ProductB createProductB();
}
// 具体工厂1
class ConcreteFactory1 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new ConcreteProductA1();
}
@Override
public ProductB createProductB() {
return new ConcreteProductB1();
}
}
// 具体工厂2
class ConcreteFactory2 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new ConcreteProductA2();
}
@Override
public ProductB createProductB() {
return new ConcreteProductB2();
}
}
// 客户端
public class Client {
public static void main(String[] args) {
AbstractFactory factory1 = new ConcreteFactory1();
ProductA productA1 = factory1.createProductA();
ProductB productB1 = factory1.createProductB();
productA1.operation(); // 输出: ConcreteProductA1 operation
productB1.operation(); // 输出: ConcreteProductB1 operation
AbstractFactory factory2 = new ConcreteFactory2();
ProductA productA2 = factory2.createProductA();
ProductB productB2 = factory2.createProductB();
productA2.operation(); // 输出: ConcreteProductA2 operation
productB2.operation(); // 输出: ConcreteProductB2 operation
}
}
解析说明:
- 抽象工厂模式提供一个接口(AbstractFactory),该接口定义了一系列相关产品的创建方法。具体工厂类(ConcreteFactory1
和 ConcreteFactory2)实现了这个接口,并分别负责创建一组相关的产品对象。 - 在上述示例中,抽象工厂(AbstractFactory)定义了创建产品A和产品B的方法(createProductA()和createProductB()),具体工厂(ConcreteFactory1和ConcreteFactory2)分别实现了这两个方法,并创建了一组相关的具体产品对象(ConcreteProductA1、ConcreteProductA2、ConcreteProductB1和 ConcreteProductB2)。
- 客户端根据需要选择合适的具体工厂,通过调用其相应的创建方法来获取相关产品对象。
- 抽象工厂模式适用于需要创建一组相关产品对象的情况,可以保证创建的产品对象之间的兼容性。
- 在 Spring 框架中,BeanFactory 和 ApplicationContext
就是抽象工厂模式的典型应用,它们负责创建和管理各种类型的 Bean 对象。Spring
的配置文件中可以定义多个具体工厂,每个具体工厂负责创建特定类型的 Bean 对象。客户端通过调用工厂的方法来获取所需的 Bean 对象。
Spring 中经典使用场景:
在 Spring 框架中,BeanFactory 和 ApplicationContext 是两个关键的接口,它们都使用了抽象工厂模式来创建和管理各种类型的 Bean 对象。
1.BeanFactory 接口的源码分析:
BeanFactory 接口是 Spring 框架的核心接口,定义了获取和管理 Bean 对象的方法。它的主要实现类是 DefaultListableBeanFactory。下面是 BeanFactory 接口的核心代码片段:
public interface BeanFactory {
Object getBean(String name) throws BeansException;
// ...
}
解析说明:
- BeanFactory 接口定义了获取 Bean 对象的方法 getBean(),通过传入 Bean 的名称(name),可以获取对应的
Bean 对象。 - 具体的 BeanFactory 实现类(如 DefaultListableBeanFactory)负责具体的 Bean 创建和管理。
- 在这个示例中,BeanFactory 接口作为抽象工厂,定义了创建 Bean 对象的方法,具体工厂类负责实现这个接口并提供相应的实现。
- 2. ApplicationContext 接口的源码分析:
ApplicationContext 接口是 BeanFactory 接口的子接口,它提供了更多的功能和扩展,包括国际化、事件发布、资源加载等。它的主要实现类是 ClassPathXmlApplicationContext。下面是 ApplicationContext 接口的核心代码片段:
public interface ApplicationContext extends BeanFactory {
// ...
}
解析说明:
- ApplicationContext 接口继承自 BeanFactory 接口,因此它包含了 BeanFactory
的所有方法,并在此基础上提供了更多的功能和扩展。 - 具体的 ApplicationContext 实现类(如 ClassPathXmlApplicationContext)在实现
BeanFactory 相关方法的同时,还提供了其他功能,如资源加载、事件发布等。 - ApplicationContext 在实际使用中常用于创建和管理 Spring 容器,并提供一种更高级的方式来配置和使用 Bean
对象。
总结:
在 Spring 框架中,BeanFactory 和 ApplicationContext 使用抽象工厂模式来创建和管理 Bean 对象。BeanFactory 接口定义了获取 Bean 的方法,具体的 BeanFactory 实现类负责具体的 Bean 创建和管理。ApplicationContext 接口继承自 BeanFactory,扩展了更多的功能,并提供了更高级的方式来配置和使用 Bean 对象。通过使用这两个接口,Spring 框架实现了抽象工厂模式的特性,使得开发者可以通过配置文件或编程方式创建和管理各种类型的 Bean 对象。
附加创建 Bean 对象可以使用多种方法:
- 使用注解:@Component、@Service、@Repository 等,用于标识类为一个 Bean 对象。通过在类上添加相应的注解,Spring 可以自动扫描并创建这些 Bean 对象。例如:
@Component
public class UserService {
// ...
}
在配置类或配置文件中,确保开启了自动扫描注解的功能,Spring 会自动创建标有注解的 Bean 对象
- 使用 XML 配置文件: 通过 XML 配置文件,我们可以显式地定义 Bean 对象并指定其类型和属性。在配置文件中,使用
元素来定义 Bean 对象,指定 ID、类名、属性等信息。例如:
<bean id="userService" class="com.example.UserService">
<property name="userRepository" ref="userRepository" />
</bean>
这样就创建了一个名为 “userService” 的 Bean 对象,并将其注入一个名为 “userRepository” 的依赖。
- 使用 Java 配置类: 使用 Java 配置类,我们可以通过编程方式来创建和配置 Bean 对象。在配置类中,使用 @Bean
注解来定义 Bean 对象的创建方法,并指定其类型和属性。例如:
@Configuration
public class AppConfig {
@Bean
public UserService userService() {
UserService userService = new UserService();
userService.setUserRepository(userRepository());
return userService;
}
@Bean
public UserRepository userRepository() {
return new UserRepository();
}
}
这样就创建了一个名为 “userService” 的 Bean 对象,并将其注入一个名为 “userRepository” 的依赖。