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.
- 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.
- 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.
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.
Curs de Patrons de Disseny de Programari
Mòdul 1: Introducció als Patrons de Disseny
- Què són els Patrons de Disseny?
- Història i Origen dels Patrons de Disseny
- Classificació dels Patrons de Disseny
- Avantatges i Desavantatges d'Usar Patrons de Disseny
Mòdul 2: Patrons Creacionals
Mòdul 3: Patrons Estructurals
Mòdul 4: Patrons de Comportament
- Introducció als Patrons de Comportament
- Chain of Responsibility
- Command
- Interpreter
- Iterator
- Mediator
- Memento
- Observer
- State
- Strategy
- Template Method
- Visitor
Mòdul 5: Aplicació de Patrons de Disseny
- Com Seleccionar el Patró Adequat
- Exemples Pràctics d'Ús de Patrons
- Patrons de Disseny en Projectes Reals
- Refactorització Usant Patrons de Disseny
Mòdul 6: Patrons de Disseny Avançats
- Patrons de Disseny en Arquitectures Modernes
- Patrons de Disseny en Microserveis
- Patrons de Disseny en Sistemes Distribuïts
- Patrons de Disseny en Desenvolupament Àgil