Java设计模式—工厂方法模式
发表于更新于
字数总计:968阅读时长:3分钟 上海
工厂方法模式(Factory Method Pattern)
工厂方法模式是一种创建型设计模式,定义一个创建对象的接口,让子类决定实例化哪一个类。
一、模式概述
1.1 定义
工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
1.2 适用场景
- 当一个类不知道它所必须创建的对象的类时
- 当一个类希望由它的子类来指定它所创建的对象时
- 当类将创建对象的职责委托给多个帮助子类中的某一个时
1.3 UML 类图
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| +----------+ +----------+ | Product | | Factory | +----------+ +----------+ | +use() | | +create()| +----△-----+ | #createProduct()| | | #registerProduct()| | +-----△-----+ +----------+ | | IDCard | +----------+ +----------+ |IDCardFactory| | +use() | +----------+ +----------+ | #createProduct()| | #registerProduct()| +----------+
|
1.4 工厂模式分类
| 类型 | 说明 | 适用场景 |
|---|
| 简单工厂 | 一个工厂类,根据参数创建不同产品 | 产品较少,不会频繁增加 |
| 工厂方法 | 每个产品对应一个工厂类 | 产品种类可能扩展 |
| 抽象工厂 | 创建多个产品族 | 多个产品族,产品之间有关联 |
二、代码实现
2.1 定义 Product 抽象类
Product类来表示产品,这个类中只声明了抽象方法use()等待子类重写。
1 2 3 4 5 6 7 8
|
public abstract class Product { public abstract void use(); }
|
1.2 定义Factory抽象类
Factory类使用了模板模式,本类定义了抽象方法 creatProduct 和 registerProduct,定义并实现了 create 方法,通过调用这个方法实现产品的注册。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
public abstract class Factory { public Product create(String owner) { Product p = createProduct(owner); registerProduct(p); return p; } protected abstract Product createProduct(String owner); protected abstract void registerProduct(Product product); }
|
1.3 定义IDCard类
继承了 Product 类并实现了 use() 方法,构造器初始化了属性 owner 和 idNum,并输出语句进行提示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
public class IDCard extends Product { private String owner; private int idNum;
IDCard(String owner, int idNum) { System.out.println("制作" + owner + "(" + idNum + ")" + "的ID卡..."); this.owner = owner; this.idNum = idNum; }
@Override public void use() { System.out.println("使用" + owner + "(" + idNum + ")" + "的ID卡..."); }
public String getOwner() { return owner; } }
|
1.4 定义IDCardFactory类
这个类继承了 Factory 并实现了其两个抽象方法,creatProduct 方法通过生成 IDCard 的实例来生成产品,registerProduct 通过将 IDCard 的 owner 保存到 List 数组中实现注册产品。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
@SuppressWarnings("all") public class IDCardFactory extends Factory {
private List<String> owners = new ArrayList<>(); private int idNum = 1001;
@Override protected Product createProduct(String owner) { return new IDCard(owner, idNum++); }
@Override protected void registerProduct(Product product) { owners.add(((IDCard) product).getOwner()); } }
|
1.5 测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
public class RunMain { public static void main(String[] args) { Factory factory = new IDCardFactory(); Product card1 = factory.create("小明"); Product card2 = factory.create("小红"); Product card3 = factory.create("小刚"); card1.use(); card2.use(); card3.use(); } }
|
2.6 运行结果

三、模式分析
3.1 优缺点
| 优点 | 缺点 |
|---|
| 符合开闭原则,扩展性好 | 类的数量增加 |
| 符合单一职责原则 | 增加系统抽象性 |
| 客户端无需知道具体产品类名 | 增加系统复杂度 |
3.2 实际应用
- Spring 的 BeanFactory:创建 Bean 实例
- JDBC 的 DriverManager:获取数据库连接
- 日志框架 SLF4J:LoggerFactory.getLogger()
1 2 3
| ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); UserService userService = context.getBean("userService", UserService.class);
|
四、总结
具体的实现内容根据工厂模式适用场景不同而变化,但是只要是工厂模式,在生成实例时就一定会用到模板模式。
设计原则:依赖倒置原则——依赖抽象,不要依赖具体类。高层模块不应该依赖低层模块,两者都应该依赖抽象。