Configuración de la clase Manager para leer y administrar la configuración de la configuración de mi programa -- java campo con file camp codereview Relacionados El problema

Setting manager class for reading and managing Settings.ini file of my program


3
vote

problema

Español

Clase de configuración de Configuración para leer y administrar la configuración de la configuración. File

He comenzado un proyecto creando Instalador de software Aplicación para descarga automática y instalación automática Software, similar cómo Ninite funciona. He creado SettingsManager.java clase para leer y administrar Configuración.ini Fichero del programa para que el resto del programa pueda usarlo. Este es solo un borrador de la clase y no está completa, pero es funcional. Me gustaría sus opiniones sobre el diseño general e implementación de este tipo de clase.

La clase SettingManager.Java

  .posts-grid {   margin-top: 25px;   display: flex;   flex-wrap: wrap; }  .posts-grid>[class*='col-'] {   display: flex;   flex-direction: column;   margin-bottom: 25px; }  .posts-grid .post {   background: #fff;   border-top: 1px solid #d5d5d5;   box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.11); }  .posts-grid .text {   padding: 8px; }  .posts-grid .card-title {   font-size: 1.25rem;   margin-bottom: 8px;   text-transform: capitalize; }  .posts-grid .read-more {   padding: 0 8px 8px 8px; }  .posts-grid .text-muted {   margin-bottom: 8px; }  .posts-grid .thumbnail img {   display: block;   width: 100%;   height: auto; }  .posts-grid p {   text-align: justify; }  .posts-grid .post {   flex-grow: 1;   display: flex;   flex-direction: column; }  .posts-grid .read-more {   margin-top: auto; }  .pagination>li>a, .pagination>li>a:hover, .pagination>li>span {   color: #585858;   line-height: 1;   padding: 6px 12px;   text-decoration: none; }  .pagination>.active>a, .pagination>.active>span, .pagination>.active>a:hover, .pagination>.active>span:hover, .pagination>.active>a:focus, .pagination>.active>span:focus {   background-color: #007bff;   border-color: #2b7c2b;   color: #fff; }  @media (max-width: 767px) {   .container {     max-width: 100%;   } }  @media (max-width: 575px) {   .container {     max-width: 100%;     padding-left: 0;     padding-right: 0;   }   .posts-grid>[class*='col-'] {     padding-left: 5px;     padding-right: 5px;   } }0  

El software.Java Enum

paquete com.zoran_jankov.software_installer.app;

  .posts-grid {   margin-top: 25px;   display: flex;   flex-wrap: wrap; }  .posts-grid>[class*='col-'] {   display: flex;   flex-direction: column;   margin-bottom: 25px; }  .posts-grid .post {   background: #fff;   border-top: 1px solid #d5d5d5;   box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.11); }  .posts-grid .text {   padding: 8px; }  .posts-grid .card-title {   font-size: 1.25rem;   margin-bottom: 8px;   text-transform: capitalize; }  .posts-grid .read-more {   padding: 0 8px 8px 8px; }  .posts-grid .text-muted {   margin-bottom: 8px; }  .posts-grid .thumbnail img {   display: block;   width: 100%;   height: auto; }  .posts-grid p {   text-align: justify; }  .posts-grid .post {   flex-grow: 1;   display: flex;   flex-direction: column; }  .posts-grid .read-more {   margin-top: auto; }  .pagination>li>a, .pagination>li>a:hover, .pagination>li>span {   color: #585858;   line-height: 1;   padding: 6px 12px;   text-decoration: none; }  .pagination>.active>a, .pagination>.active>span, .pagination>.active>a:hover, .pagination>.active>span:hover, .pagination>.active>a:focus, .pagination>.active>span:focus {   background-color: #007bff;   border-color: #2b7c2b;   color: #fff; }  @media (max-width: 767px) {   .container {     max-width: 100%;   } }  @media (max-width: 575px) {   .container {     max-width: 100%;     padding-left: 0;     padding-right: 0;   }   .posts-grid>[class*='col-'] {     padding-left: 5px;     padding-right: 5px;   } }1  

The configurants.ini < / a> archivo

Para que pueda entender mejor lo que está sucediendo en el código.

Original en ingles

Setting manager class for reading and managing Settings.ini file

I have started a project creating Software Installer application for auto download and auto install software, similar how Ninite works. I have created SettingsManager.java class for reading and managing Settings.ini file of the program so the rest of the program can use it. This is just a draft of the class an it is not complete, but it is functional. I would like your opinions on the overall design and implementation of this kind of class.

The SettingsManager.java class

package com.zoran_jankov.software_installer.app;  import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map;  import org.ini4j.Ini;  public class SettingsManager {     private static SettingsManager instance;          private static final String SETTINGS_FILE_PATH = "D:/Programing/Java/Software Installer/src/main/resources/Settings.ini";          private Map<Software, String> localRepositories = new HashMap<Software, String>();     private Map<Software, String> networkRepositories = new HashMap<Software, String>();     private Map<Software, String> onlineRepositories = new HashMap<Software, String>();     private Map<Software, String> arguments = new HashMap<Software, String>();          private SettingsManager()     {         loadSettings();     }          public static SettingsManager getInstance()     {         if(instance == null)         {             instance = new SettingsManager();         }         return instance;     }          public void loadSettings()     {         Ini settings = null;                  try         {             settings = new Ini(new File(SETTINGS_FILE_PATH));         }         catch (IOException e)         {             e.printStackTrace();         }                  localRepositories = getInstallerSettings(settings, "Local Repositories");                      networkRepositories = getInstallerSettings(settings, "Network Repositories");                          onlineRepositories = getInstallerSettings(settings, "Online Repositories");                          arguments = getInstallerSettings(settings, "Arguments");      }          private Map<Software, String> getInstallerSettings(Ini setttings, String sectionName)     {         Map<Software, String> list = new HashMap<Software, String>();                  for (Software installer : Software.values())         {             list.put(installer, setttings.get(sectionName, installer.name()));         }                  return list;     }          public String getLocalRepository(Software software)     {         return localRepositories.get(software);     }          public String getNetworkRepository(Software software)     {         return networkRepositories.get(software);     }          public String getOnlineRepository(Software software)     {         return onlineRepositories.get(software);     }          public String getArguments(Software software)     {         return arguments.get(software);     } } 

The Software.java enum

package com.zoran_jankov.software_installer.app;

public enum Software {     AIMP,     CCleaner,     DWGSee,     Firefox,     FoxitReader,     ImgBurn,     Java,     LibreOffice,     Notepad,     Office365,     OpenOffice,     RocketChat,     Skype,     SpacePlanning,     Speccy,     Thunderbird,     UltraVNC,     VLC,     ZabbixAgent,     Zip; } 

The Settings.ini file

So you can better understand what is happening in the code.

     
       
       

Lista de respuestas

4
 
vote
vote
La mejor respuesta
 

Defalt Java Style es tener los frenos de apertura en la misma línea, pero eso es hasta las preferencias. Simplemente sea consistente en su código.


  private static final String SETTINGS_FILE_PATH = "D:/Programing/Java/Software Installer/src/main/resources/Settings.ini";   

Quieres pasar ese camino, de alguna manera, ya que no es portátil.


  public class SettingsManager {     private static SettingsManager instance;      public static SettingsManager getInstance()     {         if(instance == null)         {             instance = new SettingsManager();         }         return instance;     } } 1  

Esto no es seguro, en caso de que se preocupe por ello. Un número obligatorio de hilos podría terminar con sus propios instancias no compartidas del SettingsManager . Hay tres formas de prevenir que:

La primera es usar un inicializador estático:

  public class SettingsManager {     private static SettingsManager instance;      static     {         instance = new SettingsManager();     } }   

Se garantiza que los inicializadores estáticos se sincronizarán y solo se ejecutarán una vez que se acceda a la clase.

La segunda opción es sincronizar todo el método:

  public class SettingsManager {     private static SettingsManager instance;      public static synchronized SettingsManager getInstance()     {         if(instance == null)         {             instance = new SettingsManager();         }         return instance;     } }   

Esto garantiza una sola instancia para todos, pero significa que se adquiere un bloqueo costoso para cada acceso. "Caro" en este caso significa "en comparación con simplemente obtener el valor", en el 99.99% de los casos que usted no note la diferencia de rendimiento en el método # 3.

El tercer método es verificar dos veces si el valor está disponible, una vez "barato", y luego sincronizado:

  public class SettingsManager {     private static SettingsManager instance;      public static SettingsManager getInstance()     {         if(instance == null)         {             synchronized(SettingsManager.class)             {                 if(instance == null)                 {                     instance = new SettingsManager();                 }             }         }         return instance;     } }   

que salta el bloqueo en la mayoría de los casos, excepto cuando sea necesario, a saber, si dos subprocesos intentan acceder a la instancia por primera vez.


  private static final String SETTINGS_FILE_PATH = "D:/Programing/Java/Software Installer/src/main/resources/Settings.ini";   

Quieres pasar ese camino, de alguna manera, ya que no es portátil en lo más mínimo de esta manera.

Ahora, eso lleva al problema que solo tiene una sola instancia global y, si aprovecha la ruta, debe hacerse la pregunta, qué se debe hacer cuando se solicite una segunda instancia con un camino diferente. Puede ser mejor tener una sola instancia que pase en su solicitud, o que realice a nivel mundial a lo largo de su solicitud, y no a través del nivel de clase de esta clase.


          Ini settings = null;                  try         {             settings = new Ini(new File(SETTINGS_FILE_PATH));         }         catch (IOException e)         {             e.printStackTrace();         }   

Lo más probable es que quiera volver a lanzar esa excepción, o deje que se propague libremente al permitir loadSettings8 lanzar IOException . Las excepciones de tragar silenciosamente podrían conducir a un dolor de cabeza realmente malo al depurar problemas.


  public class SettingsManager {     private static SettingsManager instance;      public static SettingsManager getInstance()     {         if(instance == null)         {             instance = new SettingsManager();         }         return instance;     } } 0  

Eso no es una lista, eso es un mapa. Nombrar así es confuso. Además, en Java 8+ puede omitir los tipos del constructor, ya que se derivan de la Declaración:

  public class SettingsManager {     private static SettingsManager instance;      public static SettingsManager getInstance()     {         if(instance == null)         {             instance = new SettingsManager();         }         return instance;     } } 1  

  public class SettingsManager {     private static SettingsManager instance;      public static SettingsManager getInstance()     {         if(instance == null)         {             instance = new SettingsManager();         }         return instance;     } } 2  

El Convenio de Java es que los miembros de Enum son constantes, por lo tanto, deben ser Upper_Snake_Case.


Ahora, lo que no quiere es que public class SettingsManager { private static SettingsManager instance; public static SettingsManager getInstance() { if(instance == null) { instance = new SettingsManager(); } return instance; } } 3 Enum, también debería ser la configuración que lee, porque eso permite facilitar el mantenimiento y la extensión del software. En general, su formato INI parece no ser adecuado para lo que desea, se parece más a que desea invertir el formato:

  public class SettingsManager {     private static SettingsManager instance;      public static SettingsManager getInstance()     {         if(instance == null)         {             instance = new SettingsManager();         }         return instance;     } } 4  

Porque con eso en su lugar, puede matar completamente public class SettingsManager { private static SettingsManager instance; public static SettingsManager getInstance() { if(instance == null) { instance = new SettingsManager(); } return instance; } } 5 completamente y haga que su solicitud sea impulsada por la configuración. Simplemente lea el archivo INI y le muestre la lista de software que está configurado en lugar de tenerlo codificado.

 

Defualt Java style is to have the opening braces on the same line, but that's down to preferences. Just be consistent in your code.


private static final String SETTINGS_FILE_PATH = "D:/Programing/Java/Software Installer/src/main/resources/Settings.ini"; 

You want to pass that path, somehow, as it is not portable.


public class SettingsManager {     private static SettingsManager instance;      public static SettingsManager getInstance()     {         if(instance == null)         {             instance = new SettingsManager();         }         return instance;     } } 

This is not thread-safe, in case you care about it. An obligatory number of threads could end up with their own, not-shared instances of the SettingsManager. There are three ways to prevent that:

The first is to use a static initializer:

public class SettingsManager {     private static SettingsManager instance;      static     {         instance = new SettingsManager();     } } 

Static initializers are guaranteed to be synchronized and will only be executed once the class is accessed.

The second option is to synchronize the whole method:

public class SettingsManager {     private static SettingsManager instance;      public static synchronized SettingsManager getInstance()     {         if(instance == null)         {             instance = new SettingsManager();         }         return instance;     } } 

This guarantees a single instance for everyone, but it means that an expensive lock is acquired for each access. "Expensive" in this case means "compared to simply getting the value", in 99.99% of the cases you will not notice the performance difference to method #3.

The third method is to check twice whether the value is available, once "cheap", and then synchronized:

public class SettingsManager {     private static SettingsManager instance;      public static SettingsManager getInstance()     {         if(instance == null)         {             synchronized(SettingsManager.class)             {                 if(instance == null)                 {                     instance = new SettingsManager();                 }             }         }         return instance;     } } 

That skips the locking in most instances, except when required, namely if two threads try to access the instance for the first time.


private static final String SETTINGS_FILE_PATH = "D:/Programing/Java/Software Installer/src/main/resources/Settings.ini"; 

You want to pass that path, somehow, as it is not portable in the slightest in this way.

Now, that leads to the problem that you only have one single, global instance, and if you pass the path you have to ask yourself the question what should be done when a second instance with a different path is requested. It might be better to have a single instance which you pass around in your application, or which you make globally accessible throughout your application, and not through the class level of this class.


        Ini settings = null;                  try         {             settings = new Ini(new File(SETTINGS_FILE_PATH));         }         catch (IOException e)         {             e.printStackTrace();         } 

You most likely want to re-throw that exception, or let it propagate freely by letting loadSettings throw IOException. Silently swallowing exceptions might lead to a really bad headache when debugging problems.


Map<Software, String> list = new HashMap<Software, String>(); 

That's not a list, that's a map. Naming like that is confusing. Also, in Java 8+ you can omit the types in the constructor, as they are derived from the declaration:

Map<Software, String> list = new HashMap<>(); 

public enum Software {     AIMP,     CCleaner, 

Java convention is that enum members are considered constants, therefor should be UPPER_SNAKE_CASE.


Now, what you don't want is that Software enum, that should be configuration that you read, too, because that allows easier maintenance and extension of the software. Overall, your ini format seems not suited for what you want, it looks more like you want to invert the format:

[AIMP] Local Repository=... Network Repository=... Online Repository=... Arguments=...  [CCleaner] Local Repository=... Network Repository=... Online Repository=... Arguments=... 

Because with that in place, you can kill off Software completely and make your application driven by configuration. You simply read the ini file and display the list of software that is configured instead of having it hard-coded.

 
 
         
         

Relacionados problema

2  Clase PHP para el manejo de archivos y la creación  ( Php class for file handling and creation ) 
Esta es una clase muy simple para manejar archivos. Permite acceder, crear y modificar archivos en el sistema o 2 archivos falsos (uno en la memoria y otros...

3  Lectura y clasificación de líneas de un archivo  ( Reading and classifying lines from a file ) 
Soy nuevo en C que estoy aprendiendo en la universidad ahora, y no estoy seguro de si lo siguiente se considera en las buenas prácticas o no. Para una asign...

6  Clasificación de palabras por frecuencia  ( Sorting words by frequency ) 
Estoy haciendo una tarea simple en óxido después de leer el Libro de óxido : Lea un archivo de texto dividirlo en Whitespace desinfectar palabras elim...

6  Programa Haskell para cambiar el nombre de las imágenes basadas en datos exif  ( Haskell program to rename images based on exif data ) 
movido originalmente de StackOverFlow , sin saber la existencia de este sitio hermano ... Debe decir que encuentro la programación en Haskell para requer...

5  Min y Max de números leen de un archivo  ( Min and max of numbers read from a file ) 
Tuve que crear este programa, y ​​lo hice bien, todo está trabajando y cosas, pero me preguntaba, ¿qué es mejor hacerlo? Quiero un método más eficiente. Asi...

2  Fusionar directorios y mantener archivos que tengan más líneas  ( Merging directories and keep files that have more lines ) 
gol Mi objetivo es combinar directorios. Cada vez que un archivo tiene el mismo nombre en dos o más directorios, solo se debe mantener el número más alto ...

4  Iterar sobre un archivo varias veces  ( Iterate over a file multiple times ) 
El objetivo del código es imprimir todas las cadenas de un archivo que coinciden con cadenas de otro archivo. Los nombres de ambos archivos son proporcionados...

9  Entrada de usuario y lectura de contenidos de archivo  ( User input and reading contents of file ) 
Para la divulgación completa: esta es una tarea para mi clase de programación y solo quiero consejos o consejos sobre algunos del código. Detalles de asigna...

2  Saltando espacios en blanco al leer el archivo  ( Skipping whitespaces when reading file ) 
En la lectura de un archivo, encontré líneas en blanco (incluso en la parte inferior) se bloquean el programa. Para solucionar esto, he agregado el siguiente ...

8  Encuentra el número más grande en una matriz  ( Find the greatest number in an array ) 
El programa lee un archivo .txt que contiene líneas de números. El primero tiene un número N y el segundo tiene números $ N $ a medida que dice la primera l...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos