0114_抽象工厂模式 (Abstract Factory Pattern)
抽象工厂模式 (Abstract Factory Pattern)
意图
提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
UML 图

优点
- 隔离了具体类的生成,使得客户端不需要知道什么被创建
- 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象
- 增加新的具体工厂和产品族很方便,无需修改已有系统,符合"开闭原则"
缺点
- 增加新的产品等级结构很复杂,需要修改抽象工厂和所有具体工厂类,违背了"开闭原则"
- 增加了系统的抽象性和理解难度
代码示例
以下是一个扩展的抽象工厂模式示例,模拟了男性(男人、男性需要的机器人)和女性(女人、女性需要的机器人)产品族创建场景。
1. 抽象产品接口 (Abstract Product Interfaces)
// 人类接口
public interface IHuman {
/**
* 吃饭行为
* 定义人类进食的基本行为
* 该方法应由实现类具体实现进食逻辑
*/
void eat();
}
// 机器人接口
public interface IRobot {
/**
* 做饭行为
* 该方法定义了机器人执行做饭任务的标准接口
* 具体实现由不同的机器人类型来完成
*/
void cook();
}
2. 具体产品 (Concrete Products)
// 男人
public class HumanMan implements IHuman {
/**
* 人类姓名属性
* 用于标识不同的人类个体
*/
private String name;
/**
* 构造方法,用于初始化人类对象
* @param name 人类姓名
*/
public HumanMan(String name) {
this.name = name;
}
/**
* 实现IHuman接口的eat方法
* 输出当前人类对象正在吃饭的信息
* 体现了人类的基本进食行为
*/
@Override
public void eat() {
System.out.println(this.name + "在吃饭");
}
}
// 女人
public class HumanWoman implements IHuman {
/**
* 人类姓名属性
* 用于标识不同的人类个体
*/
private String name;
/**
* 女性人类构造方法
* 用于创建指定姓名的女性人类对象
* @param name 人类姓名
*/
public HumanWoman(String name) {
this.name = name;
}
/**
* 实现IHuman接口的eat方法
* 重写吃饭行为,输出当前女性人类对象正在吃饭的信息
*/
@Override
public void eat() {
System.out.println(this.name + "在吃饭");
}
}
// 为男人服务的机器人
public class RobotMan implements IRobot {
/**
* 机器人的名称属性
* 用于标识不同的机器人实例
*/
private String name;
/**
* 构造方法,用于创建RobotMan实例并初始化名称
*
* @param name 机器人的名称,不能为空
*/
public RobotMan(String name) {
this.name = name;
}
/**
* 实现IRobot接口的cook方法
* 重写父接口方法,将机器人的做饭行为作为烹饪的实现
* 体现了多态性的应用
*/
@Override
public void cook() {
System.out.println(this.name + "在做饭");
}
}
// 为女性服务的机器人
public class RobotWoman implements IRobot {
/**
* 机器人的名称
*/
private String name;
/**
* 构造方法,用于初始化机器人的名称
*
* @param name 机器人的名称
*/
public RobotWoman(String name) {
this.name = name;
}
/**
* 实现IRobot接口的cook方法
* 机器人通过烹饪来展示生活技能
*/
@Override
public void cook() {
System.out.println(this.name + "在烹饪美食");
}
}
3. 抽象工厂接口 (Abstract Factory Interface)
public interface IAbstractFacotory {
/**
* 根据名称创建具体的人类对象
* @param name 人类名称
* @return 对应的人类对象实例
*/
IHuman createHuman(String name);
/**
* 根据名称创建具体的机器人对象
* @param name 机器人名称
* @return 对应的机器人对象实例
*/
IRobot createRobot(String name);
}
4. 具体工厂 (Concrete Factories)
// 男性工厂
public class ManFacory implements IAbstractFacotory {
/**
* 根据名称创建具体的人类对象
* @param name 人类名称
* @return 对应的人类对象实例(HumanMan)
*/
@Override
public IHuman createHuman(String name) {
return new HumanMan(name);
}
/**
* 根据名称创建具体的机器人对象
* @param name 机器人名称
* @return 对应的机器人对象实例(RobotMan)
*/
@Override
public IRobot createRobot(String name) {
return new RobotMan(name);
}
}
// 女性工厂
public class WomanFacory implements IAbstractFacotory {
/**
* 根据名称创建具体的女性人类对象
* @param name 人类名称
* @return 对应的女性人类对象实例
*/
@Override
public IHuman createHuman(String name) {
return new HumanWoman(name);
}
/**
* 根据名称创建具体的女性机器人对象
* @param name 机器人名称
* @return 对应的女性机器人对象实例
*/
@Override
public IRobot createRobot(String name) {
return new RobotWoman(name);
}
}
5. 客户端代码 (Client Code)
public class Test {
public static void main(String[] args) {
// 创建男性工厂实例
IAbstractFacotory manFacory = new ManFacory();
// 使用男性工厂创建人类实例
IHuman man = manFacory.createHuman("Man");
// 使用男性工厂创建机器人实例
IRobot manRobot = manFacory.createRobot("Man");
// 调用机器人的cook方法
manRobot.cook();
// 调用人类的eat方法
man.eat();
// 创建女性工厂实例
IAbstractFacotory womanFacory = new WomanFacory();
// 使用女性工厂创建人类实例
IHuman woman = womanFacory.createHuman("Woman");
// 使用女性工厂创建机器人实例
IRobot womanRobot = womanFacory.createRobot("Woman");
// 调用机器人的cook方法
womanRobot.cook();
// 调用人类的eat方法
woman.eat();
}
}
在Spring框架中的应用
抽象工厂模式在Spring框架中得到了广泛应用,特别是在Bean的创建和管理方面:
-
BeanFactory:作为Spring IoC容器的基础接口,它本身就是抽象工厂模式的体现。它定义了获取Bean的接口,而具体的实现(如
DefaultListableBeanFactory,XmlBeanFactory等)负责创建和管理Bean实例。 -
ApplicationContext:作为BeanFactory的扩展,它提供了更丰富的企业级功能,同时保持了抽象工厂的模式特性。
-
FactoryBean接口:允许用户自定义复杂的对象创建逻辑,Spring容器会调用
getObject()方法来获取实际的对象实例。
示例:
@Configuration
public class AppConfig {
@Bean
public DataSource dataSource() {
// 根据环境返回不同的数据源实现
if (isProduction()) {
return new ProductionDataSource();
} else {
return new DevelopmentDataSource();
}
}
// 其他相关Bean的定义...
}
总结
抽象工厂模式通过提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类,实现了产品家族的创建与使用的分离。它特别适合于需要确保一系列相关产品一起使用的场景,并且能够方便地切换整个产品家族。虽然增加新产品族很容易,但增加新产品等级结构会比较复杂,这是在使用时需要权衡的。

浙公网安备 33010602011771号