在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。
使用场景
- 我们不能预测要创建类的具体对象
- 我们想要一个类的子类来指定需要创建的对象
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
知名工厂方法类
- java.util.Calendar
- java.util.ResourceBundle
- java.text.NumberFormat
- java.nio.charset.Charset
- java.net.URLStreamHandlerFactory
- java.util.EnumSet
- javax.xml.bind.JAXBContext
实例
/**
*
* 定义一个包含生产对象方法的接口
*
*/
public interface Blacksmith {
Weapon manufactureWeapon(WeaponType weaponType);
}
/**
*
* 创建新对象的具体子类
*
*/
public class OrcBlacksmith implements Blacksmith {
public Weapon manufactureWeapon(WeaponType weaponType) {
return new OrcWeapon(weaponType);
}
}
/**
*
* 创建新对象的具体子类
*
*/
public class ElfBlacksmith implements Blacksmith {
public Weapon manufactureWeapon(WeaponType weaponType) {
return new ElfWeapon(weaponType);
}
}
/**
*
* 武器类型枚举
*
*/
public enum WeaponType {
SHORT_SWORD("short sword"), SPEAR("spear"), AXE("axe"), UNDEFINED("");
private String title;
WeaponType(String title) {
this.title = title;
}
@Override
public String toString() {
return title;
}
}
/**
*
* 武器接口
*
*/
public interface Weapon {
WeaponType getWeaponType();
}
/**
*
* 兽族武器
*
*/
public class OrcWeapon implements Weapon {
private WeaponType weaponType;
public OrcWeapon(WeaponType weaponType) {
this.weaponType = weaponType;
}
@Override
public String toString() {
return "Orcish " + weaponType;
}
@Override
public WeaponType getWeaponType() {
return weaponType;
}
}
/**
*
* 精灵族武器
*
*/
public class ElfWeapon implements Weapon {
private WeaponType weaponType;
public ElfWeapon(WeaponType weaponType) {
this.weaponType = weaponType;
}
@Override
public String toString() {
return "Elven " + weaponType;
}
@Override
public WeaponType getWeaponType() {
return weaponType;
}
}
/**
*
* 创建一个APP实例,它可以指示铁匠去铸造战争所使用的武器
* APP 不关心它使用的是哪一个铁匠
* APP使用配置或者根据战争的种族决定
*
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
private final Blacksmith blacksmith;
public App(Blacksmith blacksmith) {
this.blacksmith = blacksmith;
}
public static void main(String[] args) {
// 让我们使用兽族的武器去战斗吧
App app = new App(new OrcBlacksmith());
app.manufactureWeapons();
// 让我们使用精灵族的武器去战斗吧
app = new App(new ElfBlacksmith());
app.manufactureWeapons();
}
private void manufactureWeapons() {
Weapon weapon;
weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
LOGGER.info(weapon.toString());
weapon = blacksmith.manufactureWeapon(WeaponType.AXE);
LOGGER.info(weapon.toString());
}
}
输出结果
08:18:45.512 [main] INFO com.iluwatar.factory.method.App - Orcish spear
08:18:45.517 [main] INFO com.iluwatar.factory.method.App - Orcish axe
08:18:45.518 [main] INFO com.iluwatar.factory.method.App - Elven spear
08:18:45.518 [main] INFO com.iluwatar.factory.method.App - Elven axe