Skip to content

Sugerencia de mejora (refactorización) #20

@marandradec

Description

@marandradec

Un cordial saludo,
Comparto las siguientes observaciones y propuestas de refactorización basadas en la identificación de code smells y la aplicación de patrones de refactorización, con el objetivo de mejorar la legibilidad, mantenibilidad y diseño del código.

Refactorización


1️⃣ Data Class → Move Method

Problema

La clase Contact presenta el code smell Data Class, ya que contiene principalmente atributos con getters/setters y poca lógica propia.

Solución

Aplicar Move Method, trasladando métodos como getDisplayInfo() y isValid() a una clase que realmente utilice esa información, dejando a Contact como un objeto de dominio puro.

Código de la solución

class Contact {
    private String name;
    private String phoneNumber;
    private String email;

    public Contact(String name, String phoneNumber, String email) {
        this.name = name;
        this.phoneNumber = phoneNumber;
        this.email = email;
    }

    public String getDisplayInfo() {
        return "Name: " + name + ", Phone: " + phoneNumber + ", Email: " + email;
    }

    public boolean isValid() {
        return name != null && !name.trim().isEmpty() &&
               phoneNumber != null && !phoneNumber.trim().isEmpty();
    }
}

2️⃣ Long Parameter List → Preserve Whole Object

Problema

El uso de múltiples parámetros para crear o editar contactos genera Long Parameter List, aumentando la complejidad y el riesgo de errores por orden incorrecto de argumentos.

Solución

Aplicar Preserve Whole Object, pasando el objeto Contact completo a los métodos.

Código de la solución

public void addContact(Contact contact) {
    contacts.add(contact);
}

public void editContact(int index, Contact newContact) {
    if (index >= 0 && index < contacts.size()) {
        contacts.set(index, newContact);
    }
}

// Uso
Contact contact1 = new Contact("Alice", "555-1234", "alice@email.com");
contactBook.addContact(contact1);

Contact contact2 = new Contact("Bob", "555-5678", "bob@email.com");
contactBook.editContact(0, contact2);

3️⃣ Duplicate Code → Form Template Method

Problema

Existe código duplicado en la validación de índices y manejo de errores en métodos como editContact() y removeContact().

Solución

Aplicar Form Template Method, centralizando la validación en un método común reutilizable.

Código de solución

class ContactBook {
    private List<Contact> contacts;

    private void executeIfValidIndex(int index, Consumer<Integer> operation) {
        if (index >= 0 && index < contacts.size()) {
            operation.accept(index);
        } else {
            System.out.println("Invalid contact index.");
        }
    }

    public void editContact(int index, String name, String phoneNumber, String email) {
        executeIfValidIndex(index, i -> {
            Contact contact = contacts.get(i);
            contact.setName(name);
            contact.setPhoneNumber(phoneNumber);
            contact.setEmail(email);
            System.out.println("Contact updated successfully.");
        });
    }

    public void deleteContact(int index) {
        executeIfValidIndex(index, i -> {
            Contact contact = contacts.remove(i);
            System.out.println("Contact deleted: " + contact.getName());
        });
    }
}

4️⃣ Duplicate Code → Replace with Exception

Problema

La validación del índice se repite y se mezcla con la lógica principal de los métodos.

Solución

Aplicar Replace Error Code with Exception, separando validación y lógica de negocio mediante validateIndex().

Código de la solución

class ContactBook {
    private List<Contact> contacts;

    private void validateIndex(int index) {
        if (index < 0 || index >= contacts.size()) {
            throw new IndexOutOfBoundsException("Invalid contact index: " + index);
        }
    }

    public void editContact(int index, String name, String phoneNumber, String email) {
        validateIndex(index);

        Contact contact = contacts.get(index);
        contact.setName(name);
        contact.setPhoneNumber(phoneNumber);
        contact.setEmail(email);
        System.out.println("Contact updated successfully.");
    }

    public void deleteContact(int index) {
        validateIndex(index);

        Contact contact = contacts.remove(index);
        System.out.println("Contact deleted: " + contact.getName());
    }
}
try {
    contactBook.editContact(5, "Alice", "555-1234", "alice@email.com");
} catch (IndexOutOfBoundsException e) {
    System.out.println(e.getMessage());
}

5️⃣ Dead Code → Remove Dead Code

Problema

Existe dead code relacionado con el manejo de entrada que no aporta funcionalidad.

Solución

Eliminar o activar correctamente el código muerto.

Código de la solución

scanner.nextLine();

6️⃣ Dead Code → Substitute Algorithm

Problema

El uso de nextInt() genera errores por residuos en el buffer del Scanner.

Solución

Aplicar Substitute Algorithm usando nextLine() + parseInt() para un flujo más robusto.

Código de la solución

while (choice != 5) {
    System.out.println("----- Contact Book -----");
    System.out.println("1. Add a contact");
    System.out.println("2. View contacts");
    System.out.println("3. Edit a contact");
    System.out.println("4. Delete a contact");
    System.out.println("5. Exit");
    System.out.print("Enter your choice: ");

    String input = scanner.nextLine();

    try {
        choice = Integer.parseInt(input);
        System.out.println();

        switch (choice) {
            // opciones del menú
        }
    } catch (NumberFormatException e) {
        System.out.println("Invalid input. Please try again.\n");
    }
}

Agradezco de antemano su revisión y cualquier comentario que consideren pertinente.
Saludos cordiales.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions