Introducció

La refactorització és el procés de millorar el codi existent sense canviar-ne el comportament extern. L'ús de patrons de disseny en la refactorització pot ajudar a fer el codi més net, mantenible i escalable. En aquesta secció, explorarem com aplicar diferents patrons de disseny per refactoritzar codi, millorant la seva estructura i qualitat.

Objectius

  • Comprendre la importància de la refactorització.
  • Aprendre a identificar codi que necessita refactorització.
  • Aplicar patrons de disseny per millorar el codi existent.

  1. Identificació de Codi que Necessita Refactorització

Senyals de Codi que Necessita Refactorització

  • Codi duplicat: Fragments de codi que es repeteixen en diferents llocs.
  • Funcions llargues: Funcions que fan massa coses i són difícils de comprendre.
  • Classes amb massa responsabilitats: Classes que no segueixen el principi de responsabilitat única.
  • Dependències fortes: Classes que depenen fortament d'altres classes, dificultant la seva reutilització i prova.

  1. Aplicació de Patrons de Disseny en la Refactorització

Exemple 1: Refactorització amb el Patró Singleton

Problema

Suposem que tenim una classe DatabaseConnection que es crea múltiples vegades en diferents parts del codi, causant problemes de rendiment i inconsistència.

public class DatabaseConnection {
    public DatabaseConnection() {
        // Codi per establir la connexió
    }
}

Solució

Podem aplicar el patró Singleton per assegurar-nos que només hi hagi una instància de DatabaseConnection.

public class DatabaseConnection {
    private static DatabaseConnection instance;

    private DatabaseConnection() {
        // Codi per establir la connexió
    }

    public static DatabaseConnection getInstance() {
        if (instance == null) {
            instance = new DatabaseConnection();
        }
        return instance;
    }
}

Exemple 2: Refactorització amb el Patró Factory Method

Problema

Tenim una classe Shape amb subclasses Circle i Square. La creació d'objectes Shape està dispersa pel codi, fent-lo difícil de mantenir.

Shape shape1 = new Circle();
Shape shape2 = new Square();

Solució

Podem aplicar el patró Factory Method per centralitzar la creació d'objectes Shape.

public abstract class ShapeFactory {
    public abstract Shape createShape();
}

public class CircleFactory extends ShapeFactory {
    public Shape createShape() {
        return new Circle();
    }
}

public class SquareFactory extends ShapeFactory {
    public Shape createShape() {
        return new Square();
    }
}

// Ús
ShapeFactory factory = new CircleFactory();
Shape shape1 = factory.createShape();

Exemple 3: Refactorització amb el Patró Observer

Problema

Tenim una classe WeatherStation que necessita notificar múltiples pantalles quan hi ha un canvi en les dades meteorològiques.

public class WeatherStation {
    private List<Display> displays;

    public void addDisplay(Display display) {
        displays.add(display);
    }

    public void notifyDisplays() {
        for (Display display : displays) {
            display.update();
        }
    }
}

Solució

Podem aplicar el patró Observer per desacoblar la WeatherStation de les pantalles.

public interface Observer {
    void update();
}

public class WeatherStation {
    private List<Observer> observers;

    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
}

public class Display implements Observer {
    public void update() {
        // Actualitzar la pantalla
    }
}

Exercicis Pràctics

Exercici 1: Refactorització amb el Patró Singleton

Refactoritza la següent classe Logger per aplicar el patró Singleton.

public class Logger {
    public Logger() {
        // Inicialització del logger
    }

    public void log(String message) {
        // Registra el missatge
    }
}

Solució

public class Logger {
    private static Logger instance;

    private Logger() {
        // Inicialització del logger
    }

    public static Logger getInstance() {
        if (instance == null) {
            instance = new Logger();
        }
        return instance;
    }

    public void log(String message) {
        // Registra el missatge
    }
}

Exercici 2: Refactorització amb el Patró Factory Method

Refactoritza el següent codi per aplicar el patró Factory Method.

public class Notification {
    public void sendEmail() {
        // Envia un correu electrònic
    }

    public void sendSMS() {
        // Envia un SMS
    }
}

Solució

public abstract class NotificationFactory {
    public abstract Notification createNotification();
}

public class EmailNotificationFactory extends NotificationFactory {
    public Notification createNotification() {
        return new EmailNotification();
    }
}

public class SMSNotificationFactory extends NotificationFactory {
    public Notification createNotification() {
        return new SMSNotification();
    }
}

public class EmailNotification extends Notification {
    public void send() {
        // Envia un correu electrònic
    }
}

public class SMSNotification extends Notification {
    public void send() {
        // Envia un SMS
    }
}

// Ús
NotificationFactory factory = new EmailNotificationFactory();
Notification notification = factory.createNotification();
notification.send();

Conclusió

La refactorització usant patrons de disseny és una tècnica poderosa per millorar la qualitat del codi. Hem vist com aplicar alguns patrons comuns per refactoritzar codi, fent-lo més net i mantenible. Practicar aquestes tècniques en projectes reals ajudarà a consolidar els coneixements i a desenvolupar un codi de millor qualitat.

© Copyright 2024. Tots els drets reservats