一 模式定义
一个创建产品对象的工厂接口,让子类决定实例化哪一种实例对象,也就是将实际创建实例对象的工作推迟到子类当中,核心工厂类不再负责具体产品的创建。
二 模式举例
1 模式分析
我们借用三国中曹操献刀来说明这一模式的运用。抽象之后的关系如下图。
2 工厂方法模式的静态建模
大司徒王允—生成宝刀的抽象工厂
校尉曹操—具体工厂生产七星宝刀
各类宝刀—抽象产品
七星宝刀—具体产品七星宝刀
3 代码示例
3.1 建立产品
抽象宝刀——AbstractSword
package com.demo.factory.model;
/**
* 定义抽象宝刀
*
* @author Administrator
*
*/
public abstract class AbstractSword
{
// 宝刀的名字
private String name;
// 抽象父类的构造方法
public AbstractSword()
{
}
// 获得宝刀名字
public String getName()
{
return name;
}
// 设置宝刀名字
public void setName(String name)
{
this.name = name;
}
}
具体宝刀——QixingSword七星宝刀
package com.demo.factory.model.object;
import com.demo.factory.model.AbstractSword;
/**
* 七星宝刀类
*
* @author
*
*/
public class QixingSword extends AbstractSword
{
/**
* 构造方法设置宝刀的名称
*/
public QixingSword()
{
this.setName("七星宝刀");
}
}
3.2 建立工厂
抽象宝刀工厂——ISwordFactory 生产抽象宝刀
package com.demo.factory.itf;
import com.demo.factory.model.AbstractSword;
/**
* 宝刀工厂
*
* @author Administrator
*
*/
public interface ISwordFactory
{
/**
* 生产各类宝刀(返回值是抽象宝刀类型)
*
* @return
*/
public AbstractSword createSword();
}
具体宝刀工厂——Caocao 生产七星宝刀
package com.demo.factory;
import com.demo.factory.itf.ISwordFactory;
import com.demo.factory.model.AbstractSword;
import com.demo.factory.model.object.QixingSword;
/**
* 曹操具体工厂
*
* @author
*
*/
public class Caocao implements ISwordFactory
{
/**
* 实现ISwordFactory接口的createSword方法,生产七星宝刀
*/
public AbstractSword createSword()
{
return new QixingSword();
}
}
3.3 故事情节的历史重现
package com.demo;
import java.util.HashMap;
import java.util.Map;
import com.demo.factory.Caocao2;
import com.demo.factory.itf.ISwordFactory;
import com.demo.factory.model.AbstractSword;
public class MainApp
{
/**
* @param args
*/
public static void main(String[] args)
{
// 创建曹操实例对象(返回使用接口类型 ISwordFactory)
ISwordFactory swordFactory = new Caocao();
//ISwordFactory swordFactory = new Caocao2();
// 获得宝刀实例——八星宝刀
AbstractSword sword = swordFactory.createSword();
// 刺杀董卓
System.out.println("曹操使用" + sword.getName() + "刺杀董卓!");
}
}
运行结果:
曹操使用七星宝刀刺杀董卓!
3.4 用八星宝刀来考验模式
创建八星宝刀-——BaxingSword
package com.demo.factory.model.object;
import com.demo.factory.model.AbstractSword;
/**
* 八星宝刀类
*
* @author
*
*/
public class BaxingSword extends AbstractSword
{
/**
* 构造方法设置宝刀的名称
*/
public BaxingSword()
{
this.setName("八星宝刀");
}
}
创建具体宝刀工厂——Caocao2 生产八星宝刀
package com.demo.factory;
import com.demo.factory.itf.ISwordFactory;
import com.demo.factory.model.AbstractSword;
import com.demo.factory.model.object.BaxingSword;
/**
* 使用八星宝刀的曹操具体工厂
*
* @author
*
*/
public class Caocao2 implements ISwordFactory
{
// 生产八星宝刀
public AbstractSword createSword()
{
return new BaxingSword();
}
}
让曹操使用八星宝刀刺杀董卓
package com.demo;
import java.util.HashMap;
import java.util.Map;
import com.demo.factory.Caocao2;
import com.demo.factory.itf.ISwordFactory;
import com.demo.factory.model.AbstractSword;
public class MainApp
{
/**
* @param args
*/
public static void main(String[] args)
{
// 创建曹操实例对象(返回使用接口类型 ISwordFactory)
//ISwordFactory swordFactory = new Caocao();
ISwordFactory swordFactory = new Caocao2();
// 获得宝刀实例——八星宝刀
AbstractSword sword = swordFactory.createSword();
// 刺杀董卓
System.out.println("曹操使用" + sword.getName() + "刺杀董卓!");
}
}
运行结果:
曹操使用八星宝刀刺杀董卓!
三 该模式使用到的设计原则
- “开-闭”原则:一个软件实体应该对扩展开放,对修改关闭。我们在设计软件模块的时候应该使这个模块可以在不被修改的前提下被扩展。
- 依赖倒置原则:不论工厂还是产品都应该依赖于抽象,而不是具体的实现类。
四 使用场合
- 当子类型可能会有很多,以后需要不断增添不同的子类实现时。
- 当一个系统还在框架设计阶段,还不知道将来需要实例化哪些具体类时。
- 系统设计之初不需要具体对象的概念(或者没有具体对象的概念)