Cómo gestionar la estructura de un proyecto de Java

JavaJavaBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

Una estructura de proyecto efectiva es crucial para un desarrollo de Java exitoso. Esta guía integral explora los principios fundamentales de la organización de proyectos de Java, brindando a los desarrolladores conocimientos prácticos sobre cómo crear soluciones de software escalables, mantenibles y bien estructuradas.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/FileandIOManagementGroup(["File and I/O Management"]) java(("Java")) -.-> java/ConcurrentandNetworkProgrammingGroup(["Concurrent and Network Programming"]) java(("Java")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["Object-Oriented and Advanced Concepts"]) java/ObjectOrientedandAdvancedConceptsGroup -.-> java/classes_objects("Classes/Objects") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/class_methods("Class Methods") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/packages_api("Packages / API") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/oop("OOP") java/FileandIOManagementGroup -.-> java/files("Files") java/ConcurrentandNetworkProgrammingGroup -.-> java/working("Working") subgraph Lab Skills java/classes_objects -.-> lab-419476{{"Cómo gestionar la estructura de un proyecto de Java"}} java/class_methods -.-> lab-419476{{"Cómo gestionar la estructura de un proyecto de Java"}} java/packages_api -.-> lab-419476{{"Cómo gestionar la estructura de un proyecto de Java"}} java/oop -.-> lab-419476{{"Cómo gestionar la estructura de un proyecto de Java"}} java/files -.-> lab-419476{{"Cómo gestionar la estructura de un proyecto de Java"}} java/working -.-> lab-419476{{"Cómo gestionar la estructura de un proyecto de Java"}} end

Creación de una estructura básica de proyecto de Java

Los proyectos de Java siguen ciertas convenciones de organización que ayudan a los desarrolladores a gestionar el código de manera efectiva. En este paso, crearás manualmente una estructura de proyecto de Java simple para comprender los componentes fundamentales.

Comprensión de los componentes de un proyecto de Java

Un proyecto de Java normalmente contiene:

  • Archivos de código fuente (.java)
  • Archivos de bytecode compilados (.class)
  • Archivos de recursos (configuración, imágenes, etc.)
  • Documentación

Creación de una estructura de proyecto simple

Comencemos creando una estructura de proyecto básica en tu espacio de trabajo. Construiremos una simple aplicación "HelloWorld" para demostrar los conceptos.

  1. Primero, abre una terminal en tu entorno LabEx. Tu terminal ya debería estar en el directorio /home/labex/project.

  2. Crea un directorio de proyecto para nuestra aplicación de Java:

mkdir -p hello-java-app/src
cd hello-java-app
  1. Dentro del directorio src, crea un simple archivo de clase Java:
mkdir -p src/com/example/app
  1. Ahora, creemos nuestra primera clase Java. Abre el editor de código y crea un nuevo archivo llamado HelloWorld.java en la ruta hello-java-app/src/com/example/app/:
package com.example.app;

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, Java Project World!");
    }
}
  1. Compilémos este código Java. En la terminal, regresa al directorio raíz del proyecto y ejecuta:
cd /home/labex/project/hello-java-app
mkdir -p bin
javac -d bin src/com/example/app/HelloWorld.java

La salida no debería mostrar errores si la compilación fue exitosa.

  1. Ahora, ejecuta la aplicación de Java compilada:
java -cp bin com.example.app.HelloWorld

Deberías ver la siguiente salida:

Hello, Java Project World!

Comprensión de la estructura del proyecto

Revisemos lo que hemos creado:

hello-java-app/
├── bin/              ## Bytecode compilado (.class files)
│   └── com/
│       └── example/
│           └── app/
│               └── HelloWorld.class
└── src/              ## Código fuente (.java files)
    └── com/
        └── example/
            └── app/
                └── HelloWorld.java

Esta estructura sigue estos principios:

  • Separación del código fuente: Todos los archivos de código fuente de Java están en el directorio src
  • Estructura de paquetes: El paquete com.example.app corresponde a los directorios com/example/app/
  • Separación del código compilado: Los archivos de bytecode están en un directorio bin separado

Conceptos clave

  • Paquetes: Java utiliza paquetes para organizar las clases y evitar conflictos de nombres
  • Estructura de directorios: Los nombres de los paquetes se asignan directamente a las estructuras de directorios
  • Classpath: La bandera -cp le dice a Java dónde encontrar las clases compiladas

Ahora has creado manualmente una estructura básica de proyecto de Java. Esta base te ayudará a entender estructuras de proyectos más complejas utilizadas en aplicaciones del mundo real.

Organización del código Java con paquetes

En este paso, aprenderás cómo organizar tu código Java utilizando paquetes y crear una aplicación más estructurada con múltiples clases. Una adecuada organización de paquetes es esencial para proyectos de Java mantenibles.

Comprensión de las convenciones de paquetes

Los paquetes de Java siguen una convención de nomenclatura jerárquica:

  • Comienza con un nombre de dominio al revés (por ejemplo, com.example)
  • Añade el nombre del proyecto o de la organización (por ejemplo, com.example.project)
  • Añade áreas funcionales (por ejemplo, com.example.project.model)

Implementemos esta estructura en nuestro proyecto.

Creación de un proyecto con múltiples paquetes

Construiremos un simple sistema de gestión de bibliotecas con paquetes distintos para diferentes aspectos:

  1. Navega hasta el directorio de tu proyecto:
cd /home/labex/project
mkdir -p library-app/src
cd library-app
  1. Crea una disposición de paquetes estructurada:
mkdir -p src/com/example/library/model
mkdir -p src/com/example/library/service
mkdir -p src/com/example/library/util
  1. Primero, crea una clase de modelo. Abre el editor de código y crea un nuevo archivo llamado Book.java en la ruta library-app/src/com/example/library/model/:
package com.example.library.model;

public class Book {
    private String title;
    private String author;
    private int year;

    public Book(String title, String author, int year) {
        this.title = title;
        this.author = author;
        this.year = year;
    }

    // Getters
    public String getTitle() {
        return title;
    }

    public String getAuthor() {
        return author;
    }

    public int getYear() {
        return year;
    }

    @Override
    public String toString() {
        return "Book{title='" + title + "', author='" + author + "', year=" + year + "}";
    }
}
  1. A continuación, crea una clase de servicio en library-app/src/com/example/library/service/BookService.java:
package com.example.library.service;

import com.example.library.model.Book;
import java.util.ArrayList;
import java.util.List;

public class BookService {
    private List<Book> books = new ArrayList<>();

    public void addBook(Book book) {
        books.add(book);
    }

    public List<Book> getAllBooks() {
        return new ArrayList<>(books);
    }

    public Book findBookByTitle(String title) {
        for (Book book : books) {
            if (book.getTitle().equalsIgnoreCase(title)) {
                return book;
            }
        }
        return null;
    }
}
  1. Crea una clase de utilidad en library-app/src/com/example/library/util/BookFormatter.java:
package com.example.library.util;

import com.example.library.model.Book;

public class BookFormatter {
    public static String formatBookInfo(Book book) {
        return String.format("'%s' by %s (%d)",
            book.getTitle(), book.getAuthor(), book.getYear());
    }
}
  1. Finalmente, crea la clase principal de la aplicación en library-app/src/com/example/library/LibraryApp.java:
package com.example.library;

import com.example.library.model.Book;
import com.example.library.service.BookService;
import com.example.library.util.BookFormatter;

public class LibraryApp {
    public static void main(String[] args) {
        // Create service
        BookService bookService = new BookService();

        // Add some books
        bookService.addBook(new Book("The Great Gatsby", "F. Scott Fitzgerald", 1925));
        bookService.addBook(new Book("To Kill a Mockingbird", "Harper Lee", 1960));
        bookService.addBook(new Book("1984", "George Orwell", 1949));

        // Display all books
        System.out.println("Library Catalog:");
        for (Book book : bookService.getAllBooks()) {
            System.out.println(BookFormatter.formatBookInfo(book));
        }

        // Find a specific book
        Book foundBook = bookService.findBookByTitle("1984");
        if (foundBook != null) {
            System.out.println("\nFound book: " + foundBook);
        }
    }
}
  1. Compila todos los archivos Java:
mkdir -p bin
javac -d bin src/com/example/library/model/Book.java src/com/example/library/service/BookService.java src/com/example/library/util/BookFormatter.java src/com/example/library/LibraryApp.java
  1. Ejecuta la aplicación:
java -cp bin com.example.library.LibraryApp

Deberías ver la siguiente salida:

Library Catalog:
'The Great Gatsby' by F. Scott Fitzgerald (1925)
'To Kill a Mockingbird' by Harper Lee (1960)
'1984' by George Orwell (1949)

Found book: Book{title='1984', author='George Orwell', year=1949}

Comprensión de la estructura de paquetes

Examinemos la estructura que hemos creado:

library-app/
├── bin/                              ## Bytecode compilado
└── src/                              ## Código fuente
    └── com/
        └── example/
            └── library/
                ├── model/            ## Estructuras de datos
                │   └── Book.java
                ├── service/          ## Lógica de negocio
                │   └── BookService.java
                ├── util/             ## Funciones de utilidad
                │   └── BookFormatter.java
                └── LibraryApp.java   ## Aplicación principal

Principios de organización de paquetes

Esta estructura sigue importantes principios de diseño:

  1. Separación de responsabilidades:

    • Paquete model: Contiene estructuras de datos
    • Paquete service: Contiene la lógica de negocio
    • Paquete util: Contiene funciones de utilidad
  2. Agrupación lógica: Las clases relacionadas se agrupan en el mismo paquete

  3. Navegación intuitiva: La estructura de paquetes facilita la localización de una funcionalidad específica

  4. Gestión de importaciones: Las clases se referencian entre sí a través de importaciones, lo que hace que las dependencias sean claras

Al organizar el código de esta manera, se crean aplicaciones más mantenibles y escalables, más fáciles de entender y extender.

Uso de Maven para la gestión de proyectos

En este paso, aprenderás cómo utilizar Apache Maven para gestionar tu proyecto de Java. Maven es una poderosa herramienta de automatización de compilación y gestión de dependencias que simplifica la configuración y el mantenimiento de proyectos.

Comprensión de Maven

Maven proporciona:

  • Estructura de proyecto estándar
  • Gestión de dependencias
  • Automatización de la compilación
  • Gestión de información del proyecto
  • Proceso de compilación consistente en todos los proyectos

Configuración de un proyecto de Maven

Creemos un nuevo proyecto utilizando Maven:

  1. Primero, verifica si Maven está instalado:
mvn --version

Deberías ver una salida similar a esta:

Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 11.0.18, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "5.15.0-1036-azure", arch: "amd64", family: "unix"
  1. Navega hasta el directorio de tu proyecto:
cd /home/labex/project
  1. Crea un nuevo proyecto de Maven utilizando un arquetipo (una plantilla de proyecto):
mvn archetype:generate \
  -DgroupId=com.example.calculator \
  -DartifactId=simple-calculator \
  -DarchetypeArtifactId=maven-archetype-quickstart \
  -DarchetypeVersion=1.4 \
  -DinteractiveMode=false

Este comando creará un nuevo proyecto con una estructura de directorio estándar.

  1. Examina la estructura del proyecto:
cd simple-calculator
ls -la

Deberías ver una salida similar a:

total 24
drwxr-xr-x 4 labex labex 4096 ... .
drwxr-xr-x 6 labex labex 4096 ... ..
-rw-r--r-- 1 labex labex  174 ... .gitignore
-rw-r--r-- 1 labex labex  720 ... pom.xml
drwxr-xr-x 4 labex labex 4096 ... src

El archivo clave aquí es pom.xml (Project Object Model), que define la configuración del proyecto.

  1. Examina la disposición de directorios estándar de Maven:
find src -type d

Deberías ver:

src
src/main
src/main/java
src/main/java/com
src/main/java/com/example
src/main/java/com/example/calculator
src/test
src/test/java
src/test/java/com
src/test/java/com/example
src/test/java/com/example/calculator

Esta es la disposición de directorios estándar de Maven:

  • src/main/java: Código fuente
  • src/main/resources: Archivos de recursos
  • src/test/java: Código de prueba
  • src/test/resources: Recursos de prueba
  1. Echemos un vistazo al archivo App.java generado:
cat src/main/java/com/example/calculator/App.java

Deberías ver una simple clase "Hello World":

package com.example.calculator;

/**
 * Hello world!
 *
 */
public class App
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
    }
}

Mejora del proyecto de Maven

Mejoremos nuestro proyecto de calculadora agregando más clases:

  1. Crea un nuevo archivo llamado Calculator.java en src/main/java/com/example/calculator/:
package com.example.calculator;

public class Calculator {

    public int add(int a, int b) {
        return a + b;
    }

    public int subtract(int a, int b) {
        return a - b;
    }

    public int multiply(int a, int b) {
        return a * b;
    }

    public double divide(int a, int b) {
        if (b == 0) {
            throw new ArithmeticException("Cannot divide by zero");
        }
        return (double) a / b;
    }
}
  1. Ahora, modifica el archivo App.java existente para utilizar nuestra clase Calculator:
package com.example.calculator;

/**
 * Simple Calculator Application
 */
public class App
{
    public static void main( String[] args )
    {
        Calculator calculator = new Calculator();

        // Perform some calculations
        System.out.println("Addition: 5 + 3 = " + calculator.add(5, 3));
        System.out.println("Subtraction: 10 - 4 = " + calculator.subtract(10, 4));
        System.out.println("Multiplication: 6 * 7 = " + calculator.multiply(6, 7));
        System.out.println("Division: 20 / 4 = " + calculator.divide(20, 4));

        System.out.println("Calculator application completed successfully!");
    }
}
  1. Compila el proyecto utilizando Maven:
mvn compile

Deberías ver una salida que termine con:

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
  1. Empaqueta la aplicación en un archivo JAR:
mvn package

Este comando compila tu código, ejecuta las pruebas y empaqueta la aplicación.

  1. Ejecuta la aplicación empaquetada:
java -cp target/simple-calculator-1.0-SNAPSHOT.jar com.example.calculator.App

Deberías ver la salida:

Addition: 5 + 3 = 8
Subtraction: 10 - 4 = 6
Multiplication: 6 * 7 = 42
Division: 20 / 4 = 5.0
Calculator application completed successfully!

Comprensión del archivo POM de Maven

El archivo Project Object Model (POM) contiene la configuración del proyecto. Abre el archivo pom.xml en el editor y examina su estructura:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.example.calculator</groupId>
  <artifactId>simple-calculator</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>simple-calculator</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <!-- Build configuration... -->
</project>

Elementos clave en el archivo POM:

  • groupId: Identificador de la organización o del proyecto
  • artifactId: Nombre del proyecto
  • version: Versión del proyecto
  • dependencies: Bibliotecas externas utilizadas por el proyecto
  • build: Configuración para la compilación del proyecto

Comandos clave de Maven

Aquí están algunos comandos esenciales de Maven:

  • mvn compile: Compila el código fuente
  • mvn test: Ejecuta las pruebas
  • mvn package: Crea un paquete distribuible (JAR, WAR)
  • mvn install: Instala el paquete en el repositorio local
  • mvn clean: Elimina los artefactos de compilación (directorio target)
  • mvn clean install: Combinación de clean e install

Maven ha simplificado drásticamente la gestión de proyectos de Java al proporcionar convenciones, gestión de dependencias y automatización de la compilación. Este enfoque estandarizado ayuda a los desarrolladores a centrarse en escribir código en lugar de gestionar la estructura del proyecto.

Resumen

En este laboratorio, has aprendido estrategias esenciales para gestionar la estructura de proyectos de Java a través de la práctica:

  1. Comenzaste creando manualmente una estructura básica de proyecto de Java, comprendiendo los componentes fundamentales de los directorios de código fuente, paquetes y la organización del código compilado.

  2. Luego avanzaste a la creación de un proyecto más complejo con una adecuada organización de paquetes, implementando la separación de responsabilidades al dividir la funcionalidad en paquetes de modelo, servicio y utilidad.

  3. Finalmente, aprendiste cómo utilizar Maven, una poderosa herramienta de automatización de compilación, para crear y gestionar proyectos de Java estandarizados con gestión de dependencias y procesos de compilación automatizados.

Estas habilidades fundamentales servirán como una base sólida para tu futuro trabajo de desarrollo de Java, lo que te permitirá crear aplicaciones bien organizadas, mantenibles y escalables. Al seguir las convenciones establecidas y las mejores prácticas para la estructura de proyectos, colaborarás de manera más efectiva con otros desarrolladores y producirás código de mayor calidad.