摘选自:《设计模式Java手册》
工厂方法模式的核心思想
一个方法能够创建一个对象,这本身并不意味着该方法是工厂方法模式的一个例子。总而言之,实现了工厂方法模式的特征是:
- 该方法创建了一个新对象
- 该方法的返回类型为一个抽象类或接口
- 有若干个类实现了上述抽象类型
Arrays.asList()方法实例化了一个对象,并且其返回类型为一个接口,有的人可能会认为这种方法也是工厂模式的一个例子。尽管使用这类方法的用户也不知道到底要实例化哪个类,但是它不是工厂方法模式的例子。工厂方法模式的核心思想是:让对象的创建者代替用户确定应该实例化哪一个类。
决定要实例化的类
假定A公司计划允许客户赊购焰火制品。在赊购系统的早期设计阶段,我们负责开发一个CreditCheckOnline类,该类用于审查一名客户是否有资格向A公司赊购一定数额的产品。
开发开始后,我们发现赊购代理偶尔会离线。项目分析人员决定,在这种情况下,系统应为呼叫中心代表提供一个对话框,呼叫中心代表通过想客户询问对话框上列出的问题来确定是否允许该客户进行赊购。针对这个设计,我们创建了一个CreditCheckOffline类。起初,我们设计了两个类,CreditCheckOnline和CreditCheckOffline,他们都实现了同一个方法:creditLimit(id:int) : double
这样,无论联机赊购代理是否在线,我们都可以根据图1所示的两个类确定用户的限额。现在的问题是,这两个类的用户必须知道该实例化哪个类。但是,现在只有我们知道赊购代理是否在线!
在这个时候,我们可以让这两个类实现一个接口,并创建一个方法,此方法的返回类型为这个接口。具体而言,我们可以:
- 创建一个包含creditLimit()方法的接口CreditCheck。
- 修改上面两个赊购审查类的声明,使他们实现CreditCheck接口。
- 创建一个CreditCheckFactory类,在该类中提供createCreditCheck()方法,此方法的返回类型为 CreditCheck接口。
这样,在实现createCreditCheck()方法的时候,我们可以根据赊购代理的状态决定实例化哪个类。通过应用工厂模式,无论赊购代理是否在线,客户代码都能够通过调用createCreditCheck()方法获取赊购对象。