[英]Multiple subclases with singleton pattern and static methods & variables
對我的英語感到抱歉,我能盡力解釋這個問題。
問題
我有多個類,從唯一的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類。 其他條款“延伸”了這一點。
失敗 :
由於“父”類具有靜態方法,因此不會替換它們。 變量總是具有相同的值。
Posible Solution我讀到了“工廠模式”,但是如果它解決了我的問題則沒有,這基本上是為每個類重新編寫代碼,如果我進行更改則更容易維護
我試着想辦法做到這一點,但我想不出比以前測試過的更好的東西
這是XML文件:
如果有人需要進一步解釋或更好地解釋(我的英語不好),我會嘗試再次更清楚地解釋
由於您當前的方法是由一系列反模式構成的,因此我將從一些一般性考慮開始。 這不是解決您的問題,但可能會指導您的方式。 缺少一些基本信息,但根據代碼,我將做出以下假設:
以下是我的建議:
應該避免在WebApp中使用靜態聲明,至少如果您不想應對所有“線程安全”注意事項。 如果您想要查看WebApplication的Scopes的單個實例,尤其是您的案例中的ApplicationScope 。 這樣你應該擺脫靜態問題。
如何構建代碼以僅加載XML文件一次並應用不同的“Reader-Logic” CommandPattern將告訴您。 你提到了子類化,這將是它的一部分。
讀取XML文件的代碼的和平不需要是靜態的。 只需檢查數據是否已加載,就像您在已應用的單例模式中檢查實例一樣。
在Java中,請不要使用大寫變量名。 始終以小寫字母開頭。
為了獲得更具體的答案,有些人需要了解XML-Content的生命周期 。 它是靜態的還是在服務器運行時會改變? 在后一種情況下,您可以應用基於時間的緩存實現。 其中有一堆用於Java。
再見,理解你的英語絕對沒問題,希望同樣適用於我的;-)
我會使用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);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.