Principio aperto / chiuso in Java

1. Panoramica

In questo tutorial, discuteremo il principio Open / Closed (OCP) come uno dei principi SOLID della programmazione orientata agli oggetti.

Nel complesso, entreremo nei dettagli su cos'è questo principio e su come implementarlo durante la progettazione del nostro software.

2. Principio aperto / chiuso

Come suggerisce il nome, questo principio afferma che le entità software dovrebbero essere aperte per l'estensione, ma chiuse per la modifica. Di conseguenza, quando i requisiti aziendali cambiano, l'entità può essere estesa, ma non modificata.

Per l'illustrazione seguente, ci concentreremo su come le interfacce sono un modo per seguire OCP.

2.1. Non conforme

Consideriamo che stiamo creando un'app calcolatrice che potrebbe avere diverse operazioni, come addizioni e sottrazioni.

Prima di tutto, definiremo un'interfaccia di primo livello - CalculatorOperation :

public interface CalculatorOperation {}

Definiamo una classe Addition , che aggiungerebbe due numeri e implementerebbe C alculatorOperation :

public class Addition implements CalculatorOperation { private double left; private double right; private double result = 0.0; public Addition(double left, double right) { this.left = left; this.right = right; } // getters and setters }

A partire da ora, abbiamo solo una classe Addition, quindi dobbiamo definire un'altra classe denominata Subtraction :

public class Subtraction implements CalculatorOperation { private double left; private double right; private double result = 0.0; public Subtraction(double left, double right) { this.left = left; this.right = right; } // getters and setters }

Definiamo ora la nostra classe principale, che eseguirà le operazioni della calcolatrice:

public class Calculator { public void calculate(CalculatorOperation operation) { if (operation == null) { throw new InvalidParameterException("Can not perform operation"); } if (operation instanceof Addition) { Addition addition = (Addition) operation; addition.setResult(addition.getLeft() + addition.getRight()); } else if (operation instanceof Subtraction) { Subtraction subtraction = (Subtraction) operation; subtraction.setResult(subtraction.getLeft() - subtraction.getRight()); } } }

Sebbene possa sembrare corretto, non è un buon esempio dell'OCP. Quando un nuovo requisito di aggiungere funzionalità di moltiplicazione o divisione entra, abbiamo alcun modo oltre a cambiare il calcolo metodo della calcolatrice di classe.

Quindi, possiamo dire che questo codice non è conforme a OCP.

2.2. Conformità OCP

Come abbiamo visto, la nostra app calcolatrice non è ancora conforme a OCP. Il codice nel metodo di calcolo cambierà con ogni nuova richiesta di supporto operativo in arrivo. Quindi, dobbiamo estrarre questo codice e metterlo in un livello di astrazione.

Una soluzione è delegare ogni operazione nella rispettiva classe:

public interface CalculatorOperation { void perform(); }

Di conseguenza, la classe Addition potrebbe implementare la logica dell'aggiunta di due numeri:

public class Addition implements CalculatorOperation { private double left; private double right; private double result; // constructor, getters and setters @Override public void perform() { result = left + right; } }

Allo stesso modo, una classe Subtraction aggiornata avrebbe una logica simile. E analogamente a Addition and Subtraction , come nuova richiesta di modifica, potremmo implementare la logica di divisione :

public class Division implements CalculatorOperation { private double left; private double right; private double result; // constructor, getters and setters @Override public void perform() { if (right != 0) { result = left / right; } } }

Infine, la nostra classe Calculator non ha bisogno di implementare una nuova logica quando introduciamo nuovi operatori:

public class Calculator { public void calculate(CalculatorOperation operation) { if (operation == null) { throw new InvalidParameterException("Cannot perform operation"); } operation.perform(); } } 

In questo modo la classe viene chiusa per la modifica ma aperta per un'estensione.

3. Conclusione

In questo tutorial, abbiamo imparato cos'è l'OCP per definizione, quindi elaborato quella definizione. Abbiamo quindi visto un esempio di una semplice applicazione calcolatrice che era difettosa nel suo design. Infine, abbiamo migliorato il design facendolo aderire all'OCP.

Come sempre, il codice è disponibile su GitHub.