工厂模式:简单工厂&抽象工厂

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一,它提供了一种创建对象的方式,使得创建对象的过程与使用对象的过程分离。
工厂模式提供了一种创建对象的方式,而无需指定要创建的具体类。

简单工厂模式

接口及其实体类:

public interface Shape {  
    void draw();  
}  
  
// 实现圆形类  
class Circle implements Shape {  
    @Override  
    public void draw() {  
        System.out.println("绘制圆形");  
    }  
}  
  
// 实现矩形类  
class Rectangle implements Shape {  
    @Override  
    public void draw() {  
        System.out.println("绘制矩形");  
    }  
}  
  
// 实现三角形类  
class Triangle implements Shape {  
    @Override  
    public void draw() {  
        System.out.println("绘制三角形");  
    }  
}

工厂类:
注:这里利用反射创建对象,采用泛型控制输入参数必须是Shape的实现类

// 形状工厂类  
class ShapeFactory {  
    public <T extends Shape > T getShape(Class<T> c) {  
        T shape = null;  
        try {  
            shape = c.getDeclaredConstructor().newInstance();  
        } catch (Exception e) {  
            System.out.println("类加载失败");  
        }  
        return shape;  
    }  
}

测试运行:

public class example {  
    public static void main(String[] args) {  
        ShapeFactory shapeFactory = new ShapeFactory();  
  
        Circle shape = shapeFactory.getShape(Circle.class);  
        shape.draw();  
  
        Triangle shape1 = shapeFactory.getShape(Triangle.class);  
        shape1.draw();  
  
        Rectangle shape2 = shapeFactory.getShape(Rectangle.class);  
        shape2.draw();  
    }  
}

结果:

绘制圆形
绘制三角形
绘制矩形

工厂方法模式

工厂方法模式没用改变实体类的代码,而是拓展了工厂类,定义了一个创建对象的工厂接口(或者抽象类),让工厂子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。
比如修改工厂类如下:

// 形状工厂类  
abstract class ShapeFactory {  
    public abstract <T extends Shape > T getShape(Class<T> c);  
}  
  
class ShapeFactoryImpl extends ShapeFactory {  
    public <T extends Shape> T getShape(Class<T> c) {  
        T t = null;  
        try {  
            t = c.getDeclaredConstructor().newInstance();  
        } catch (Exception e) {  
            System.out.println("类加载失败");  
        }  
        return t;  
    }  
}

相较于简单工厂模式,工厂类的拓展相对更加简单。

抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。主要作用是可以提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。

// 家具抽象工厂接口
interface FurnitureFactory {
    Furniture createFurniture();
}

// 现代风格家具工厂
class ModernFurnitureFactory implements FurnitureFactory {
   	@Override
    public Furniture createFurniture() {
        return new Furniture(new ModernChair(),new ModernTable());
    }
}

// 复古风格家具工厂
class VintageFurnitureFactory implements FurnitureFactory {  
	@Override
    public Furniture createFurniture() {
        return new Furniture(new VintageChair(),new VintageTable());
    }
}

比如对于实体类,假设有两个产品(椅子,桌子),两种风格(现代,复古),两两排列组合总共有4种家具,这里给出了两种家具的工厂,一种生产现代,一种复古。避免使用时候创建家具过于麻烦。

优点:

  1. 具体产品在应用层的代码隔离,无需关系创建的细节
  2. 将一个系列的产品统一到一起创建
    缺点:
  3. 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难;

spring中的工厂模式

Spring IOC容器使用工厂模式来管理对象的创建和生命周期。容器作为工厂负责实例化Bean并管理它们的生命周期,主要是beanfactory和applicationcontext两个接口,这两个接口就是spring管理bean的两个顶级抽象工厂。

public interface BeanFactory {
    String FACTORY_BEAN_PREFIX = "&";

    Object getBean(String name) throws BeansException;

    <T> T getBean(String name, Class<T> requiredType) throws BeansException;

    Object getBean(String name, Object... args) throws BeansException;

    <T> T getBean(Class<T> requiredType) throws BeansException;

    <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
    //...
}

AbstractBeanFactory 是 BeanFactory 的抽象实现类,实现了 getBean方法的核心逻辑。其中包含spring读取BeanDefinition对象,从缓存中找需要的bean,判断是否有依赖bean,最后创建单例bean。(跳转spring的bean生命周期)

protected <T> T doGetBean(
        String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
        throws BeansException {

    String beanName = transformedBeanName(name);
    Object bean;

    // 尝试从缓存中获取单例 Bean
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        if (logger.isTraceEnabled()) {
            if (isSingletonCurrentlyInCreation(beanName)) {
                logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                        "' that is not fully initialized yet - a consequence of a circular reference");
            }
            else {
                logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }
    else {
        // ...
        // 创建新的 Bean 实例
        if (mbd.isSingleton()) {
            sharedInstance = getSingleton(beanName, () -> {
                try {
                    return createBean(beanName, mbd, args);
                }
                catch (BeansException ex) {
                    // ...
                }
            });
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
        }
        // ...
    }
    // ...
    return (T) bean;
}

参考

Spring源码解析:BeanFactory深入理解-CSDN博客

posted @ 2025-04-26 21:12  fff友人A  阅读(18)  评论(0)    收藏  举报