0113_工厂方法(Factory Method)

工厂方法(Factory Method)

意图: 定义一个创建对象的接口,但让子类决定实例化哪个类
UML图:
MethodFactory
优点:

  1. 一个调用者想创建一个对象,只要知道其名称就可以了。
  2. 扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
  3. 屏蔽产品的具体实现,调用者只关心产品的接口。

缺点:
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

代码示例:

以下是一个简单的工厂方法模式示例,模拟了普通人和机器人的创建场景。

1. 产品接口 (Product Interface)

public interface IHuman {
    /**
     * 吃饭行为
     * 定义人类进食的基本行为
     */
    void eat();

}

2. 具体产品 (Concrete Products)

public class Human implements IHuman {
    /**
     * 人类姓名属性
     * 用于标识不同的人类个体
     */
    private String name;

    /**
     * 构造方法,用于初始化人类对象
     * @param name 人类姓名
     */
    public Human(String name) {
        this.name = name;
    }

    /**
     * 实现IHuman接口的eat方法
     * 输出当前人类对象正在吃饭的信息
     */
    @Override
    public void eat() {
        System.out.println(this.name + "在吃饭");
    }

}

public class Robot implements IHuman {
    /**
     * 机器人的名称
     */
    private String name;

    /**
     * 构造方法,用于初始化机器人的名称
     *
     * @param name 机器人的名称
     */
    public Robot(String name) {
        this.name = name;
    }

    /**
     * 实现IHuman接口的eat方法
     * 机器人通过充电来模拟人类的进食行为
     */
    @Override
    public void eat() {
        System.out.println(this.name + "在充电");
    }

}

3. 创建者抽象类 (Creator Abstract Class)

public interface IMethodFacotory {
    /**
     * 根据名称创建具体的人类对象
     * @param name 人类名称
     * @return 对应的人类对象实例
     */
    IHuman createHuman(String name);
}

4. 具体创建者 (Concrete Creators)

public class HumanFacory implements IMethodFacotory{
    /**
     * 根据名称创建具体的人类对象
     * @param name 人类名称
     * @return 对应的人类对象实例
     */
    public IHuman createHuman(String name) {
        return new Human( name);
    }
}
public class RobotFacory implements IMethodFacotory{
    /**
     * 根据名称创建机器人实例
     * @param name 机器人的名称
     * @return 返回一个新的Robot对象
     */
    public IHuman createHuman(String name) {
        return new Robot( name);
    }
}

5. 客户端代码 (Client Code)

public class Test {
    public static void main(String[] args) {
        // 创建具体工厂 - 人类工厂
        IMethodFacotory humanFactory = new HumanFacory();
        // 创建具体产品 - 人类实例
        IHuman human = humanFactory.createHuman("张三");
        // 调用人类的吃饭行为
        human.eat();
        
        // 切换为机器人工厂
        IMethodFacotory robotFactory = new RobotFacory();
        // 创建具体产品 - 机器人实例
        IHuman robot = robotFactory.createHuman("机器人");
        // 调用机器人的吃饭行为
        robot.eat();
    }
}

在Spring框架中的应用

工厂方法模式在Spring中得到了极致的使用。最典型的例子就是BeanFactoryApplicationContext接口。

  • BeanFactory 是Spring IoC容器的基础接口,其核心方法 getBean(String name) 就是一个工厂方法。
  • 当你调用 ctx.getBean("myService") 时,容器会根据你的配置(XML、注解或Java Config)来决定是返回一个已经存在的单例Bean,还是创建一个新的原型Bean,或者是返回一个被代理包装后的Bean。具体的创建逻辑(即使用哪个具体的工厂)由Spring在启动时根据你的配置来决定和实现。

总结

工厂方法模式通过让子类决定创建的对象类型,来达到将对象创建的过程封装的目的,使得代码更加灵活和可扩展,符合“开闭原则”(对扩展开放,对修改关闭)。它是解耦框架代码的利器。

posted @ 2025-08-28 08:09  庞去广  阅读(13)  评论(0)    收藏  举报