簡體   English   中英

具有單例模式和靜態方法及變量的多個子子句

[英]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文件:

http://pastebin.com/aXS0aCxP

  • 我使用大寫字母來變量名稱,因為它是“靜態的”,我用它將它與其他變量分開。 通常我使用java命名法
  • XML文件包含webapp URL和有關Webapp的其他信息(domain,port..etc)。 只有這個信息改變了( paginasGlobales

如果有人需要進一步解釋或更好地解釋(我的英語不好),我會嘗試再次更清楚地解釋

由於您當前的方法是由一系列反模式構成的,因此我將從一些一般性考慮開始。 這不是解決您的問題,但可能會指導您的方式。 缺少一些基本信息,但根據代碼,我將做出以下假設:

  • 您正在開發WebApplication(* .war)
  • 您希望將存儲在XML文件中的信息緩存一段未知的時間。
  • 您希望分離代碼以加載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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM