您现在的位置是:首页 >技术交流 >设计模式之工厂模式网站首页技术交流

设计模式之工厂模式

简介设计模式之工厂模式

如果你还可以努力、可以付出,就不要轻言停止和放弃。在你停止努力的那一刻之前,一切都还没有什么真正的结果。


简单工厂模式

简单工厂模式(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;
    // ...
}

解析说明:

  1. BeanFactory 接口定义了获取 Bean 对象的方法 getBean(),通过传入 Bean 的名称(name),可以获取对应的
    Bean 对象。
  2. 具体的 BeanFactory 实现类(如 DefaultListableBeanFactory)负责具体的 Bean 创建和管理。
  3. 在这个示例中,BeanFactory 接口作为抽象工厂,定义了创建 Bean 对象的方法,具体工厂类负责实现这个接口并提供相应的实现。
  4. 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” 的依赖。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。