1.什么是工厂方法
工厂方法模式(Factory Method Pattern):简称为 工厂模式 又可称作 虚拟构造器模式 或 多态工厂模式
定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。 属于设计模式三大分类中的创建型模式
,作为抽象工厂模式的孪生兄弟
工厂方法模式包含以下4个角色:
Product(抽象产品)
ConcreteProduct(具体产品)
Factory(抽象工厂)
ConcreteFactory(具体工厂)
类图:
工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象
目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类
2.应用场景
-
客户只知道创建产品的工厂名,而不知道具体的产品名。如 小米电视工厂、海信电视工厂等。
-
创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口。
-
客户不关心创建产品的细节,只关心产品的品牌。
3.优缺点
-
优点:用户只需要关系所需产品对应的工厂,无须关心创建细节;
加入新产品符合开闭原则,提高可扩展性。
-
缺点:类的个数容易过多,增加复杂度;
增加了系统的抽象性和理解难度。
4.代码实现
例如:**用工厂方法设计电动自行车工厂的模拟程序。**为每种品牌的电动自行车提供一个子工厂,如爱玛工厂专门负责生产爱玛(Aima)牌电动自行车,雅迪工厂专门负责生产雅迪(Yadea)牌电动自行车。如果今后需要生产台铃(Tailg)牌电动自行车,只需要增加一个新的台铃电动自行车工厂即可,无须修改原有代码,使得整个系统具有更强的灵活性和可扩展性。
类图:
代码:
interface Bicycle {
public void show();
}
class Aima implements Bicycle{
public void show() {
System.out.println("爱玛自行车好!");
}
}
class Yadea implements Bicycle{
public void show() {
System.out.println("雅迪自行车好!");
}
}
//工厂
interface Factory {
public Bicycle produce();
}
class AimaFactory implements Factory{
public Bicycle produce() {
System.out.println("爱玛自行车生产了!");
Aima aima=new Aima();
return aima;
}
}
class YadeaFactory implements Factory{
public Bicycle produce() {
System.out.println("雅迪自行车生产了!");
Yadea yadea=new Yadea();
return yadea;
}
}
public class Client {
public static void main(String[] args) {
Factory factory;
Bicycle bicycle;
factory= (Factory) lab.XMLUtil.getBean();
bicycle=factory.produce();
bicycle.show();
}
}
public class XMLUtil {
public static Object getBean(){
try{
DocumentBuilderFactory dFactory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=dFactory.newDocumentBuilder();
Document doc;
doc=builder.parse(new File("src//lab//config.xml"));
NodeList nl=doc.getElementsByTagName("className");
Node classNode=nl.item(1).getFirstChild();
String cName=classNode.getNodeValue();
System.out.println("新类名:"+cName);
Class c=Class.forName(cName);
Object obj=c.newInstance();
return obj;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<config>
<className>lab.AimaFactory</className>
<className>lab.YadeaFactory</className>
</config>
5.扩展
当需要生成的产品不多且不会增加,一个具体工厂类就可以完成任务时,可删除抽象工厂类。这时工厂方法模式将退化到简单工厂模式,其结构图如图所示: