反射机制
- Java反射:指在程序运行时获取已知名称的类或已有对象 的相关信息的一种机制,包括类的方法、属性、父类等信 息,还包括实例的创建和实例类型的判断等
- Class类的实例:表示正在运行的Java应用程序中的类和接口,其forName(String className)方法可以返回与带有给定字符串名的类或接口相关联的 Class对象,再通过 Class对象的 newInstance()方法创建此对象所表示的类 的一个新实例,即通过一个类名字符串得到类的实例
//通过类名生成实例对象并将其返回
Class c=Class.forName(“java.lang.String");
Object obj=c.newInstance();
return obj;
配置文件
- 纯文本文件,例如XML文件,properties文件……等
- 通常是XML文件,可以将类名存储在配置文件中,例 如具体工厂类的类名
定义XMLUtil类 有getByNames方法和getBean方法
//designpatterns.factorymethod.XMLUtil.java
package game.refactoring.finished.r3.config;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;
import java.net.URL;
public class XMLUtil {
// 该方法用于从XML配置文件中提取让所需的信息,返回一个字符串对象
public String getByName(String nameStr) {
try {
String ret;
// 创建DOM文档对象
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
// String XMLfile="src//game//refactoring//finished//r3//config//config.xml";
String XMLFileStr = "/game/refactoring/finished/r3/config/config.xml";
URL XMLFileURL = this.getClass().getResource(XMLFileStr);
doc = builder.parse(XMLFileURL.openConnection().getInputStream());
// 获取包含类名的文本结点
NodeList nl = doc.getElementsByTagName(nameStr);
Node classNode = nl.item(0).getFirstChild();
ret = classNode.getNodeValue();
return ret;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
// 该方法用于从XML配置文件中提取让所需的信息,返回一个字符串数组对象
public String[] getByNames(String nameStr) {
try {
String[] ret;
// 创建DOM文档对象
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
// String XMLfile="src//game//refactoring//finished//r3//config//config.xml";
String XMLFileStr = "/game/refactoring/finished/r3/config/config.xml";
URL XMLFileURL = this.getClass().getResource(XMLFileStr);
doc = builder.parse(XMLFileURL.openConnection().getInputStream());
// 获取包含类名的文本结点
NodeList nl = doc.getElementsByTagName(nameStr);
ret = new String[nl.getLength()];
for (int i = 0; i < nl.getLength(); i++) {
Node classNode = nl.item(i).getFirstChild();
ret[i] = classNode.getNodeValue();
}
return ret;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
// 该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象
public Object getBean() {
try {
// 创建DOM文档对象
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("src//designpatterns//factorymethod//config.xml"));
// 获取包含类名的文本结点
NodeList nl = doc.getElementsByTagName("className");
Node classNode = nl.item(0).getFirstChild();
String cName = classNode.getNodeValue();
// 通过类名生成实例对象并将其返回
Class c = Class.forName(cName);
Object obj = c.newInstance();
return obj;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
之后可以:
<?xml version="1.0"?>
<config>
<className>designpatterns.factorymethod.DatabaseLoggerFactory</className>
<player1>A</player1>
<player2>B</player2>
<startPoint>○</startPoint>
<endPoint>▓</endPoint>
<luckyTurn>¤</luckyTurn>
<landMine>★</landMine>
<pause>■</pause>
<timeTunnel>〓</timeTunnel>
<common>-</common>
<roleNames>关羽</roleNames>
<roleNames>张飞</roleNames>
<roleNames>吕布</roleNames>
<roleNames>赵云</roleNames>
<playerIDs>玩家1</playerIDs>
<playerIDs>玩家2</playerIDs>
</config>
玩家:
package game.refactoring.finished.r3.config;
public class PlayerInfoFromXML implements IPlayerInfo {
private XMLUtil xmlUtil = new XMLUtil();
@Override
public String[] getPlayerRoles() {
return xmlUtil.getByNames("roleNames");
}
@Override
public String[] getPlayerIDs() {
return xmlUtil.getByNames("playerIDs");
}
}
地图:
package game.refactoring.finished.r3.config;
public class MapSymbolsFromXML implements IMapSymbols {
private XMLUtil xmlUtil = new XMLUtil();
@Override
public String getPlayer1() {
return xmlUtil.getByName("player1");
}
@Override
public String getPlayer2() {
return xmlUtil.getByName("player2");
}
@Override
public String getStartPoint() {
return xmlUtil.getByName("startPoint");
}
@Override
public String getEndPoint() {
return xmlUtil.getByName("endPoint");
}
@Override
public String getLuckyTurn() {
return xmlUtil.getByName("luckyTurn");
}
@Override
public String getLandMine() {
return xmlUtil.getByName("landMine");
}
@Override
public String getPause() {
return xmlUtil.getByName("pause");
}
@Override
public String getTimeTunnel() {
return xmlUtil.getByName("timeTunnel");
}
@Override
public String getCommon() {
return xmlUtil.getByName("common");
}
}