¿Qué diseño elegir para analizar diferentes archivos para rellenar diferentes clases?

7

Actualmente estoy trabajando en un proyecto que requiere analizar diferentes tipos de archivos. El contenido de los archivos llenará las clases.

eg: file1 populate content of class1,  file2 populate content of class2, etc.

Mi pregunta es ¿dónde debería ir la lógica de análisis del archivo?

1st option : si coloco la lógica de análisis dentro de la clase, la clase se vuelve realmente enorme, porque actualmente la clase en sí es de ~ 400 líneas y crecerá en el futuro. La ventaja de esta manera es que las cosas son realmente simples, podría usar el operador > & gt ;, etc.

2nd option : cree una nueva clase que tome std::istream y la referencia de clase, haga la lógica de análisis allí y rellene la clase. La ventaja de esta forma de hacer es que si la clase sigue siendo la misma pero el formato del archivo cambia,

eg: 'file1 populate content of class1 or file1-v2 populate content of class1'

Tengo que usar el polimorfismo para cambiar la lógica de análisis y mantener el diseño simple. La desventaja de esta opción es que es un poco complejo pero puedo vivir con ella.

¿Qué opción crees que es mejor o hay alguna otra opción mejor?

    
pregunta vanta mula 17.10.2017 - 01:41

2 respuestas

9

Las clases deben tener una responsabilidad única . Presumiblemente, la responsabilidad de analizar un archivo para poblar una clase y las responsabilidades de la clase en sí son distintas y no deben combinarse. Por lo tanto, la segunda opción es el mejor diseño.

Es bastante común que los formatos de archivo cambien a medida que se desarrolle un sistema, y al separar esta preocupación ahora, estará en un buen lugar si cambian el formato de archivo o la clase que está poblando. También es un diseño que permite una mayor flexibilidad, por ejemplo, si decide que desea poblar su clase desde la red, un formato de archivo diferente, etc.

    
respondido por el Samuel 17.10.2017 - 03:28
9

Si el análisis es más complejo que unas pocas líneas de código, probablemente sea mejor ubicarlo en clases separadas, llamémoslas Class1Parser , Class2Parser y así sucesivamente. Si esas clases contienen partes similares, puede:

  • cree una clase base común BaseParser para ambas partes donde se encuentran las partes reutilizables

  • cree una clase de utilidad ParserUtil para funciones reutilizables

  • convierte el analizador en una clase genérica como Parser<T> donde T es Class1 o Class2

  • use una combinación de las opciones anteriores (como hacer solo el ParserUtil o BaseParser genérico)

Tenga en cuenta que una jerarquía de herencia de los analizadores ahora puede ser independiente de la jerarquía de herencia de las clases analizadas, esto no sería posible si se pone la lógica de análisis directamente en Class1 / Class2 .

Ninguna de estas opciones debería impedirle implementar un operator>> para Class1 o Class2 , si cree que lo necesita para facilitar su uso. Este operador puede simplemente delegar su funcionalidad a un objeto de tipo Class1Parser o Class2Parser .

Si estos enfoques terminan siendo más complejos que poner la lógica del analizador en Class1 o Class2 , entonces hay algo totalmente incorrecto en su código. En esencia, debería ser la misma lógica . Al poner la lógica de análisis en clases separadas, se desacopla de otros métodos en esas clases, lo que debería reducir la complejidad general, no aumentarla.

    
respondido por el Doc Brown 17.10.2017 - 05:19

Lea otras preguntas en las etiquetas