工厂方法模式:又称工厂模式,也叫虚拟构造器模式或者多态工厂模式,属于类创建型模式。
在这个模式中,有4个角色
1.抽象工厂
在抽象工厂类中,声明了工厂方法,用于返回一个产品。是整个模式的核心,它与应用程序无关。任何在模式中创建对象的工厂类都必须实现该接口。
2.具体工厂
是抽象工厂类的子类,实现了父类中的工厂方法。由客户调用,返回具体产品。
3.抽象产品
抽象产品是定义产品的接口,是所有产品的共同父类或者接口。
4.具体产品
实现抽象产品接口,由专门的具体工厂创建。一个具体产品只能由某一个具体工厂创建,一一对应。优点:用户只需要关心所需产品的工厂,无需知道其他细节,添加时不需要改动原来的代码,只需要增加具体工厂和具体产品类。也体现了缺点:每多一个具体产品,需要多写一个具体产品类和一个具体工厂类。
举例:
有抽象产品类 电视机,具体产品 海尔电视机和海信电视机。
有抽象工厂类 生产电视机制造厂,具体工厂 海尔制造厂和海信制造厂。
package factory; public class HisenseTVFactory implements TVFactory{ public TV produceTV() { System.out.println("海信工厂 生产 海信电视机"); return new HisenseTV(); } }
package factory; public abstract class TV{ public abstract void play(); }//TV作为抽象产品类,可以是接口或者抽象类。包含了所有产品都具有的业务方法play()
package factory; public interface TVFactory{ public TV produceTV(); }//抽象工厂类,可以是接口或者抽象类,包含了抽象的工厂方法produceTV(),返回抽象产品TV类型的对象
package factory; public class HisenseTV extends TV{ public void play() { System.out.println("具体产品类海信电视机"); } }
package factory; public class HaierTVFactory implements TVFactory{ public TV produceTV() { System.out.println("海尔工厂 生产 海尔电视机"); return new HaierTV(); } }
package factory; public class HisenseTV extends TV{ public void play() { System.out.println("具体产品类海信电视机"); } }
<?xml version="1.0"?> <config> <className>HaierTVFactory</className> </config>
1 package factory; 2 3 import javax.xml.parsers.*; 4 import org.w3c.dom.*; 5 import java.io.*; 6 import java.net.URL; 7 8 public class XMLUtil { 9 10 public static Object getBean() { 11 try { 12 //创建DOM文档对象 13 DocumentBuilderFactory dFactory=DocumentBuilderFactory.newInstance();//文档制造者工厂创建了一个 文档制造者工厂对象 14 DocumentBuilder builder=dFactory.newDocumentBuilder();//文档制造者类 通过 文档制造者工厂 创造一个 文档制造者对象 15 Document doc;//文档制造者 创建 文档 16 doc=builder.parse(new File("src/factory/TV.xml"));//解析xml文件 17 18 //获取包含类名的文本节点 19 NodeList nl=doc.getElementsByTagName("className");//文本节点列表里有很多被className标签夹着的内容 20 Node classNode=nl.item(0).getFirstChild(); 21 //item(0)表示引用列表里第一个节点,这里只有一个。getFirstChild表示获取该节点的第一个孩子。 22 String cName=classNode.getNodeValue(); 23 24 //通过类名生成实例对象并返回,cName=HaierTVFactory 25 Class c=Class.forName("factory." + cName); 26 Object obj=c.newInstance(); 27 return obj; 28 }catch(Exception e) { 29 e.printStackTrace(); 30 return null; 31 } 32 } 33 }
1 package factory; 2 3 public class Client { 4 5 public static void main(String[] args) { 6 try { 7 TV tv; 8 TVFactory factory; 9 factory=(TVFactory)XMLUtil.getBean();//getBean返回类型为Object,此处需要强转 10 tv=factory.produceTV();//多态:父类栈变量 引用(指向)子类对象 11 tv.play(); 12 }catch(Exception e) { 13 System.out.println(e.getMessage()); 14 } 15 } 16 }
输出:
海尔工厂 生产 海尔电视机
具体产品类海尔电视机
包里各文件和路径:
Java反射是指程序运行时获取已知名称的类或已有对象的相关信息的一种机制,包括类的方法、属性、超类等信息,还包括实例的对象和实例类型的判断等。在反射中使用最多的类是Class,Class类的实例表示正在运行的Java应用程序中的类和接口,其forName(String className)方法可以返回与 带有给定字符串名的类或接口 相关联的Class对象,再通过Class对象的newInstance()方法创建此对象所表示的类的一个新实例,即通过一个类名字符串得到类的实例。
Class c=Class.forName(cName); Object obj=c.newInstance(); return obj;