¿Cómo debo estructura de una aplicación Java, donde puedo poner mis clases?

StackOverflow https://stackoverflow.com/questions/7596

  •  08-06-2019
  •  | 
  •  

Pregunta

Primero de todo, quiero saber cómo construir una aplicación Java.Pero siempre me ha intrigado acerca de donde poner mis clases.Hay partidarios de la organización de los paquetes en un estricto dominio orientados a la moda, otros se separan por nivel.

Yo siempre he tenido problemas con

  • nomenclatura,
  • la colocación de

Así,

  1. ¿Dónde poner tu dominio específicos constantes (y ¿cuál es el mejor nombre para una clase)?
  2. ¿Dónde se coloca clases de cosas, que es tanto de la infraestructura y de dominio específico (por ejemplo yo tengo un FileStorageStrategy clase, que almacena los archivos en la base de datos, o bien en la base de datos)?
  3. Donde poner las Excepciones?
  4. Hay algunos estándares a la que puedo consultar?
¿Fue útil?

Solución

Realmente he llegado a la Experta Estándar De Diseño Del Directorio.

Una de las ideas clave, para mí, es tener dos fuentes raíces - uno para el código de producción y uno para el código de la prueba así:

MyProject/src/main/java/com/acme/Widget.java
MyProject/src/test/java/com/acme/WidgetTest.java

(aquí, tanto en src/main/java y src/test/java, son fuente de raíces).

Ventajas:

  • Las pruebas han de paquete (o "default") nivel de acceso a sus clases bajo prueba.
  • Usted puede fácilmente paquete sólo sus fuentes de producción dentro de un FRASCO, dejando de src/test/java como una fuente de la raíz.

Una regla de oro sobre la colocación de la clase y los paquetes:

Hablando en general, bien estructurado proyectos estará libre de las dependencias circulares.Aprender cuando son malos (y cuando se no), y considerar la posibilidad de una herramienta como JDepend o SonarJ que le ayudará a eliminarlos.

Otros consejos

Soy un gran fan de las organizaciones de fuentes, por lo que siempre se cree la siguiente estructura de directorios:

/src - for your packages & classes
/test - for unit tests
/docs - for documentation, generated and manually edited
/lib - 3rd party libraries
/etc - unrelated stuff
/bin (or /classes) - compiled classes, output of your compile
/dist - for distribution packages, hopefully auto generated by a build system

En /src estoy utilizando el valor predeterminado de patrones Java:Los nombres de los paquetes a partir de su dominio (org.sudominio.yourprojectname) y la clase de los nombres que reflejan la programación orientada a objetos aspecto al que se está creando con la clase (ver los otros comentaristas).Común de los nombres de los paquetes como util, modelo, ver, eventos son útiles también.

Yo tiendo a poner constantes para un tema específico en una clase propia, como SessionConstants o ServiceConstants en el mismo paquete de las clases de dominio.

Donde estoy trabajando, estamos usando Maven 2 y tenemos un buen arquetipo de nuestros proyectos.El objetivo fue obtener una buena separación de las preocupaciones, con lo que hemos definido una estructura de proyecto, el uso de varios módulos (uno para cada aplicación "capa"):- común:el código común de los utilizados por el resto de capas (por ejemplo, i18n) - entidades:las entidades de dominio - repositorios:este módulo contiene los daos interfaces e implementaciones - servicios-intf:las interfaces de los servicios (e.g, UserService, ...) - servicios-impl:las implementaciones de los servicios (e.g, UserServiceImpl) - web:todo lo relacionado con el contenido de la web (por ejemplo, css, jsp, jsf páginas, ...) - lr:servicios web

Cada módulo tiene su propio dependencias (por ejemplo, los repositorios podría haber jpa) y del proyecto (por lo tanto pertenecen al módulo común).Las dependencias entre los diferentes módulos de proyecto claramente separadas de las cosas (por ejemplo, la capa de web depende de la capa de servicio, pero no sabe sobre el repositorio de la capa).

Cada módulo tiene su propio paquete de base, por ejemplo, si el paquete de la aplicación es "com.foo.bar", entonces tenemos:

com.foo.bar.common
com.foo.bar.entities
com.foo.bar.repositories
com.foo.bar.services
com.foo.bar.services.impl
...

Cada módulo respeta el estándar de proyecto de maven estructura:

   src\
   ..main\java
     ...\resources
   ..test\java
     ...\resources

La unidad de pruebas para una determinada capa encontrar fácilmente su lugar en \src est...Todo lo que es de dominio específico que tiene lugar en las entidades del módulo.Algo así como un FileStorageStrategy deben ir en los repositorios de módulo, ya que no necesita saber exactamente lo que la aplicación es.En la capa de servicios, sólo sabemos que la interfaz del repositorio, no nos importa lo que la implementación específica es (separación de preocupaciones).

Hay varias ventajas de este enfoque:

  • la separación clara de las preocupaciones
  • cada módulo es packageable como una jarra (o de una guerra en el caso de que el módulo web) y por lo tanto facilita la reutilización de código (por ejemplo, se podrían instalar el módulo en el repositorio de maven y reutilizarlo en otro proyecto)
  • la máxima independencia de cada parte del proyecto

Sé que esto no responda a todas sus preguntas, pero creo que esto podría poner en el camino correcto y que podrían resultar útiles a los demás.

Los nombres de clase siempre debe ser descriptivo y explicativo.Si tiene varios dominios de la responsabilidad de sus clases, a continuación, probablemente debería de ser refactorizado.

Igualmente para usted paquetes.Deben ser agrupados por el dominio de la responsabilidad.Cada dominio tiene sus propias excepciones.

En general, no se preocupan por ella hasta que llegues a un punto donde cada vez es abrumadora y la hinchada.A continuación, sentarse y no el código, sólo refactorizar las clases, recopilar con regularidad para asegurarse de que todo funciona.Luego, continúe como se hizo antes.

El uso de los paquetes relacionados con el grupo funcionalidad juntos.

Generalmente la parte superior de su árbol de paquetes es su nombre de dominio a la inversa (com.domain.subdomain) para garantizar la unicidad, y, por lo general, habrá un paquete para su aplicación.Luego subdividir que por relacionados con el área, por lo que su FileStorageStrategy podría ir en, digamos, com.domain.subdomain.myapp.storage, y , a continuación, no puede ser más específicos implementaciones subclases/lo que sea en com.domain.subdomain.myapp.storage.file y com.domain.subdomain.myapp.storage.database.Estos nombres pueden llegar a ser muy larga, pero import mantiene todos ellos en la parte superior de los archivos y de los IDEs pueden ayudar a manejar así.

Las excepciones suelen ir en el mismo paquete que las clases que tirarlos, así que si usted tenía, digamos, FileStorageException sería ir en el mismo paquete FileStorageStrategy.Asimismo, una interfaz que define las constantes estaría en el mismo paquete.

Realmente no hay ninguna norma y, como tal, sólo tiene que utilizar el sentido común, y si todo resulta demasiado complicado, refactorizar!

Una cosa que me pareció muy útil para la unidad de pruebas era tener un myApp/src/ y también myApp/test_src/ directorios.De esta manera, puedo realizar pruebas de unidad en los mismos paquetes, ya que las clases se ponen a prueba, y, sin embargo, que fácilmente se pueden excluir los casos de prueba cuando preparo mi instalación de producción.

Respuesta corta:dibujar la arquitectura del sistema en términos de los módulos, puestas lado a lado, con cada módulo en rodajas verticalmente en capas (por ejemplo,la vista, el modelo de persistencia).A continuación, utilice una estructura como com.mycompany.myapp.somemodule.somelayer, por ejemplo, com.mycompany.myapp.cliente.ver o com.mycompany.myapp.servidor.modelo.

Utilizando el nivel superior de los paquetes para la aplicación módulos, en la vieja usanza equipo-sentido de la ciencia la programación modular, debería ser obvio.Sin embargo, en la mayoría de los proyectos que he trabajado terminamos olvidando a hacer eso, y terminar con un lío de paquetes sin que la estructura de nivel superior.Este anti-patrón generalmente se muestra a sí mismo como un paquete para algo como 'oyentes' o 'acciones' que los grupos de las clases no relacionadas simplemente porque resulta que implementan la misma interfaz.

Dentro de un módulo, o en una aplicación pequeña, el uso de los paquetes de las capas de la aplicación.Probablemente los paquetes incluyen cosas como la siguiente, dependiendo de la arquitectura:

  • com.mycompany.myapp.ver
  • com.mycompany.myapp.modelo
  • com.mycompany.myapp.servicios
  • com.mycompany.myapp.reglas
  • com.mycompany.myapp.la persistencia (o 'dao' para la capa de acceso a datos)
  • com.mycompany.myapp.util (tenga cuidado de que esto no se utilizan como si se tratara de 'misc')

Dentro de cada una de estas capas, es natural que a las clases en grupo por tipo, si hay un montón.Un común anti-patrón aquí es innecesariamente introducir demasiados paquetes y los niveles de sub-paquete de modo que sólo hay un par de clases en cada paquete.

Creo que sea sencillo y no creo que sea.No abstracto y capa demasiado.Simplemente mantenerlo limpio, y a medida que crece, la refactorización es trivial.Una de las mejores características de los IDEs es refactorización, así que ¿por qué no hacer uso de ella y ahorrar energía de cerebro para resolver problemas que están relacionados con su aplicación, en lugar de meta temas como el código de la organización.

Una cosa que he hecho en el pasado - si estoy ampliación de una clase voy a tratar de seguir sus convenciones.Por ejemplo, al trabajar con el Framework Spring, voy a tener mi Controlador MVC clases en un paquete que se llama com.mydomain.myapp.web.servlet.mvc Si no estoy extendiendo algo que me acaba de ir con lo que es más simple.com.mydomain.dominio para el Dominio de los Objetos (aunque, si usted tiene un montón de objetos de dominio este paquete podría ser un poco difícil de manejar).Para el dominio específico de las constantes, de hecho, me puso como público constantes en la mayoría de los relacionados con la clase.Por ejemplo, si tengo un "Miembro" de la clase y tener un máximo miembro de la longitud del nombre de la constante, lo puse en el Miembro de la clase.Algunas tiendas, realice una de las Constantes de la clase, pero no veo el valor en la formación de grumos no relacionados números y cadenas de caracteres en una sola clase.He visto algunas otras tiendas de tratar de resolver este problema mediante la creación de SEPARAR las Constantes de clases, pero que apenas se parece como una pérdida de tiempo y el resultado es demasiado confuso.El uso de esta configuración, un gran proyecto con varios desarrolladores van a duplicar las constantes de todo el lugar.

Me gusta romper mis clases en paquetes que están relacionados unos con otros.

Por ejemplo:Modelo Para la base de datos de las llamadas relacionadas con la

Ver Las clases que se ocupan de lo que se ve

Control Núcleo de la funcionalidad de las clases

Util Cualquier misc.las clases que se utilizan (normalmente las funciones estáticas)

etc.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top