工厂方法模式是简单工厂模式的延伸,它继承了简单工厂模式的优点,同时弥补了简单工厂的缺陷,更好地符合开闭原则的要求,增加新的具体产品对象不需要对已有系统作任何修改。
工厂方法模式又称为工厂模式,也叫虚拟构造器模式或者多态工厂模式,属于类创建模式。在工厂模式中,工厂父类负责定义产品对象的公共接口,而子工厂模式负责生成具体的产品对象,这样做的目的是将产品类实例化操作延迟到工厂子类中完成,即通过工厂子类来确定实例化哪一个对象。
Product(抽象产品)
抽象产品是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的共同父类接口
ConcreteProduct(具体产品)
具体产品实现抽象产品接口,某种类型的具体产品由专门具体创建
Facory(抽象工厂)
在抽象工厂类中,声明工厂方法,用于返回一个产品。抽象工厂是工厂方法模式的核心,任何在模式中创建对象的工厂类都必须实现该接口。
ConcreteFactory(具体工厂)
具体工厂是抽象工厂类的子类,实现了抽象工厂定义的工厂方法,返回一个具体产品类的实例。
在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建的工作交给了子类。核心类仅仅给出具体工厂实现的接口,而不负责哪一个产品被实例化的细节,使得工厂方法模式允许系统在不修改工厂角色的情况下引进新产品。
实际的开发应用中,不直接使用new关键字来创建对象,而是将具体类的类名写入配置文件,在通过java反射机制,读取XML格式的配置文件,根据存储在XML文件的类名字符串生成对象。
之前的简单工厂模式时我们也创建过一个类似实例,但却是违反了开闭原则的。通过工厂方法模式进行一次重构,将原有工厂进行分割,为每种品牌的手机提供一个子工厂,使整个系统具有更好的灵活性和可扩展性。
抽象产品类Phone
public abstract class Phone {
public abstract void use();
}
具体产品类HuaweiPhone
public class HuaweiPhone extends Phone {
@Override
public void use() {
System.out.println("华为手机使用中....");
}
}
具体产品类XiaomiPhone
public class XiaomiPhone extends Phone {
@Override
public void use() {
System.out.println("小米手机使用中....");
}
}
抽象工厂类PhoneFactory
public interface PhoneFactory {
Phone producePhone();
}
具体工厂类HuaweiPFactory
public class HuaweiPFactory implements PhoneFactory {
@Override
public Phone producePhone() {
System.out.println("华为工厂生产华为手机......");
return new HuaweiPhone();
}
}
具体工厂类XiaomiPFactory
public class XiaomiPFactory implements PhoneFactory {
@Override
public Phone producePhone() {
System.out.println("小米工厂生产小米手机......");
return new XiaomiPhone();
}
}
XML操作工具类
public class XMLUtilPhone {
public static Object getBean() throws Exception {
//创建解析器工厂
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
//创建解析器
DocumentBuilder builder = builderFactory.newDocumentBuilder();
//得到document
Document document = builder.parse("configPhone.xml");
//获取包含品牌名称的文本节点
NodeList brandNameList = document.getElementsByTagName("factoryName");
Node classNode = brandNameList.item(0).getFirstChild();
String factoryName = classNode.getNodeValue().trim();
// System.out.println(factoryName);
Class c = Class.forName("com.factoryMethod." + factoryName);
Object o = c.newInstance();
return o;
}
}
配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<factoryName>XiaomiPFactory</factoryName>
</configuration>
测试类
public class Test {
public static void main(String[] args) throws Exception {
PhoneFactory phoneFactory = (PhoneFactory) XMLUtilPhone.getBean();
Phone phone = phoneFactory.producePhone();
phone.use();
}
}
结果分析
如果在配置文件将节点中内容设置为 XiaomiPFactory,则输出结果如下:
如果在配置文件将节点中内容设置为 XiaomiPFactory,则输出结果如下:
如果需要增加新的类型的手机,则首先要增加一个新的具体产品类,再增加对于的具体工厂类。
原文:https://www.cnblogs.com/Yee-Q/p/12431131.html