问题
我有多个类,它从唯一的XML文件中读取更多字符串。
所有这些clases都从同一个文件中读取,但变量是不同的。因为每个类都读取文档的不同部分。
这个变量我想用“静态”。因为每次我使用该类时我都不想实例化。
我使用这些类来返回“动态”URL。我在Forms,Links,JSP和“request.getRequestDispatcher(#)”中使用这些URL。
这就是为什么使用“静态”方式不在JSP / Servlet中实例化类并且可以直接使用它。 (代码更简单,更干净)
班级示例:
public class PaginasProductos {
Logger log = LoggerFactory.getLogger(getClass());
// URL donde se encuentran las paginas
private static String PATH;
// URL para las acciones
private static String RealPath = PaginasGlobales.getPATH();
//Paginas
private static String PaginaListados;
private static String FormularioModificar;
private static String FormularioAlta;
// Acciones = Servlets
private static String AccionAlta;
private static String AccionBaja;
private static String AccionListar;
private static String AccionModificar;
private static String AccionObtener;
// Instancia de la clase
private static PaginasProductos INSTANCIA;
/**
* Devuelve las URL de las paginas especificas de administracion de productos
* @return Una instancia con todas las URL de las paginas
*/
public static PaginasProductos getInstance(){
if (INSTANCIA == null) INSTANCIA = new PaginasProductos();
return INSTANCIA;
}//Final del metodo, getInstance
private PaginasProductos(){
String rutaTotal = InicializadorXML.getRutaXmlPaginas();
SAXBuilder constructor = new SAXBuilder();
File xml = new File(rutaTotal);
try{
Document documento = (Document) constructor.build(xml);
Element root = documento.getRootElement();
List<Element> listado = root.getChildren("paginasProductos");
for (int contador = 0; contador < listado.size(); contador++){
Element parametro = (Element) listado.get(contador);
PATH = parametro.getChildText("path");
PaginaListados = PATH+parametro.getChildText("listado");
FormularioModificar = PATH+parametro.getChildText("formularioMod");
FormularioAlta = RealPath+PATH+parametro.getChildText("formularioAlta");
AccionAlta = RealPath+parametro.getChildText("alta");
AccionBaja = RealPath+parametro.getChildText("baja");;
AccionListar = RealPath+parametro.getChildText("listar");
AccionModificar = RealPath+parametro.getChildText("modificar");
AccionObtener = RealPath+parametro.getChildText("obtener");
}
}catch (IOException e) {
log.error("Ex (IOException | Constructor | PaginaProductos): " + e.getMessage());
log.error("¡traza!", e);
}catch (JDOMException e) {
log.error("Ex (IOException | Constructor | PaginaProductos): " + e.getMessage());
log.error("¡traza!", e);
}catch (Exception e) {
log.error("Ex (Exception | Constructor | PaginaProductos): " + e.getMessage());
log.error("¡traza!", e);
}
} //Fin Constructor PaginasClientes
@SuppressWarnings("javadoc")
public static String getPaginaListados() {
return PaginaListados;
}
@SuppressWarnings("javadoc")
public static String getFormularioModificar() {
return FormularioModificar;
}
@SuppressWarnings("javadoc")
public static String getFormularioAlta() {
return FormularioAlta;
}
@SuppressWarnings("javadoc")
public static String getAccionAlta() {
return AccionAlta;
}
@SuppressWarnings("javadoc")
public static String getAccionBaja() {
return AccionBaja;
}
@SuppressWarnings("javadoc")
public static String getAccionListar() {
return AccionListar;
}
@SuppressWarnings("javadoc")
public static String getAccionModificar() {
return AccionModificar;
}
@SuppressWarnings("javadoc")
public static String getAccionObtener() {
return AccionObtener;
}} //Fin Clase PaginasClientes
现在我所做的是相同的代码,替换“paginasProductos”,为每个类读取他们的XML部分。
但我认为存在另一种方法。因为我认为我可以重用代码而不是每个类再次写入
我尝试过的事情
生成包含此代码的Abstract类。其他条款“扩展”了这一点。
故障:
由于“父”类具有静态方法,因此不会替换它们。变量总是具有相同的值。
可行解决方案 我读到了“工厂模式”,但是如果它解决了我的问题,那就基本上重新编写每个类的代码,如果我做出更改就更容易维护
我试着想办法,但我想不出比以前测试过的更好的东西
这是XML文件:
如果有人需要进一步解释或更好地解释(我的英语不好),我会尝试再次更清楚地解释
答案 0 :(得分:1)
由于您目前的方法是由一系列反模式构成的,因此我将从一些一般性考虑开始。这不是解决您的问题,但可能会指导您的方式。缺少一些基本信息,但根据代码,我将做出以下假设:
以下是我的建议:
应该避免在WebApp中使用静态声明,至少如果您不想应对所有“线程安全”注意事项。如果您想要查看WebApplication的范围的单个实例,尤其是您的案例中的 ApplicationScope 。这样你就可以摆脱静态问题。
如何构建代码以仅加载XML文件一次并应用不同的“Reader-Logic” CommandPattern 将告诉您。你提到了子类化,这将是它的一部分。
读取XML文件的代码的和平不需要是静态的。只需检查数据是否已加载,就像您在已应用的单例模式中检查实例一样。
在Java中,请不要使用大写变量名。始终以小写字母开头。
为了获得更具体的答案,有些人需要了解XML-Content的生命周期。它是静态的还是在服务器运行时会改变?在后一种情况下,您可以应用基于时间的缓存实现。其中有很多都是为了Java。
再见,理解你的英语绝对没问题,希望同样适用于我的; - )
答案 1 :(得分:1)
我会使用HashMap
来存储产品。如果您需要添加新产品,只需向productos
添加新值即可。你可以发布你的XML文件吗?
public class PaginasProductos {
private HashMap<String,String> paginasProductos;
private String[] productos = {"listado", "formularioMod", ...};
.....
public PaginasProductos(){
String rutaTotal = InicializadorXML.getRutaXmlPaginas();
SAXBuilder constructor = new SAXBuilder();
File xml = new File(rutaTotal);
try{
Document documento = (Document) constructor.build(xml);
Element root = documento.getRootElement();
List<Element> listado = root.getChildren("paginasProductos");
PATH = parametro.getChildText("path");
for (int contador = 0; contador < listado.size(); contador++){
Element parametro = (Element) listado.get(contador);
for(String producto:productos){
paginasProductos.put(producto, PATH+parametro.getChildText(producto));
}
}
}
}
public String getProducto(String producto){
return paginasProductos.get(producto)
}
}
修改强>
根据您提供的XML(下面的代码段),您的代码可以简化。
<paginasProductos>
<path>administracion/productos/</path>
<listado>gestionProductos.jsp</listado>
<formularioMod>formularioModificarProducto.jsp</formularioMod>
<formularioAlta>formularioAltaProducto.jsp</formularioAlta>
<alta>AltaProducto</alta>
<baja>BajaProducto</baja>
<listar>ListarProductos</listar>
<modificar>ModificarProducto</modificar>
<obtener>ObtenerProducto</obtener>
</paginasProductos>
重构代码无需了解productos
。只需在<paginasProductos>
代码中添加另一个子元素,即可生成新的producto
。
public class PaginasProductos {
private HashMap<String,String> paginasProductos;
.....
public PaginasProductos(){
String rutaTotal = InicializadorXML.getRutaXmlPaginas();
SAXBuilder constructor = new SAXBuilder();
File xml = new File(rutaTotal);
try{
Document documento = (Document) constructor.build(xml);
Element root = documento.getRootElement();
List<Element> listado = root.getChildren("paginasProductos");
PATH = parametro.getChildText("path");
for (int contador = 0; contador < listado.size(); contador++){
Element parametro = (Element) listado.get(contador);
paginasProductos.put(parametro.getTagName(), PATH+parametro.getChildText(producto));
}
}
}
public String getProducto(String producto){
return paginasProductos.get(producto)
}
}
修改强>
根据您的评论,您可以进一步重构:
public class Paginas {
private HashMap<String,String> paginas;
.....
// sectionName = "paginasProductos", etc.
public Paginas(String sectionName ){
String rutaTotal = InicializadorXML.getRutaXmlPaginas();
SAXBuilder constructor = new SAXBuilder();
File xml = new File(rutaTotal);
try{
Document documento = (Document) constructor.build(xml);
Element root = documento.getRootElement();
List<Element> listado = root.getChildren(sectionName );
PATH = parametro.getChildText("path");
for (int contador = 0; contador < listado.size(); contador++){
Element parametro = (Element) listado.get(contador);
paginas.put(parametro.getTagName(), PATH+parametro.getChildText(producto));
}
}
}
public String getPaginas(String page){
return paginas.get(page);
}
}
现在,您为XML文件中的每个组创建一个Paginas
实例。也许你可以有一个PaginasManager来保持它们在一起。
public class PaginasManager{
private HashMap<String,String> paginasSections;
....
public PaginasManager(String[] sectionNames){
for(String sectionName:sectionNames){
paginasSections.put(sectionName, new Paginas(sectionName));
}
}
public String getPaginas(String section, String page){
return paginasSections.get(section).get(page);
}
}