Åbn / lukket princip i Java

1. Oversigt

I denne vejledning diskuterer vi Open / Closed Principle (OCP) som et af SOLID-principperne for objektorienteret programmering.

Samlet set vil vi gå i detaljer om, hvad dette princip er, og hvordan vi implementerer det, når vi designer vores software.

2. Åben / lukket princip

Som navnet antyder, hedder dette princip, at softwareenheder skal være åbne for udvidelse, men lukkes for ændringer. Som et resultat, når forretningskravene ændres, kan virksomheden udvides, men ikke ændres.

For nedenstående illustration, vi fokuserer på, hvordan grænseflader er en måde at følge OCP på.

2.1. Ikke-kompatibel

Lad os overveje, at vi bygger en lommeregner-app, der muligvis har flere operationer, såsom tilføjelse og subtraktion.

Først og fremmest definerer vi et interface på øverste niveau - Lommeregner:

offentlig grænseflade CalculatorOperation {}

Lad os definere en Tilføjelse klasse, som tilføjer to tal og implementerer Calculator Drift:

public class Addition implementerer CalculatorOperation {privat dobbelt til venstre; privat dobbelt ret; privat dobbelt resultat = 0,0; offentlig tilføjelse (dobbelt til venstre, dobbelt til højre) {this.left = venstre; this.right = højre; } // getters og setters}

Fra nu af har vi kun en klasse Tilføjelse, så vi er nødt til at definere en anden klasse, der hedder Subtraktion:

offentlig klasse Subtraktion implementerer CalculatorOperation {privat dobbelt til venstre; privat dobbelt ret; privat dobbelt resultat = 0,0; offentlig subtraktion (dobbelt til venstre, dobbelt til højre) {this.left = venstre; this.right = højre; } // getters og setters}

Lad os nu definere vores hovedklasse, som udfører vores lommeregneroperationer:

public class Calculator {public void calculate (CalculatorOperation operation) {if (operation == null) {throw new InvalidParameterException ("Kan ikke udføre operation"); } if (operation instanceof Addition) {Addition addition = (Addition) operation; addition.setResult (addition.getLeft () + addition.getRight ()); } ellers hvis (operation instanceof Subtraction) {Subtraction subtraction = (Subtraction) operation; subtraction.setResult (subtraction.getLeft () - subtraction.getRight ()); }}}

Selvom dette kan virke fint, er det ikke et godt eksempel på OCP. Når et nyt krav om tilføjelse af multiplikations- eller opdelingsfunktionalitet kommer ind, har vi ingen måde udover at ændre Beregn metode til Lommeregner klasse.

Derfor kan vi sige, at denne kode ikke er OCP-kompatibel.

2.2. OCP-kompatibel

Som vi har set, er vores lommeregner-app endnu ikke OCP-kompatibel. Koden i Beregn metoden ændres med hver indkommende nye anmodning om support til operation. Så vi er nødt til at udtrække denne kode og lægge den i et abstraktionslag.

Én løsning er at delegere hver operation i deres respektive klasse:

offentlig grænseflade CalculatorOperation {ugyldig udføre (); }

Som et resultat af dette Tilføjelse klasse kunne implementere logikken med at tilføje to tal:

public class Addition implementerer CalculatorOperation {privat dobbelt til venstre; privat dobbelt ret; privat dobbelt resultat // constructor, getters and setters @Override public void perform () {result = venstre + højre; }}

Ligeledes en opdateret Subtraktion klasse ville have lignende logik. Og på samme måde som Tilføjelse og Subtraktion, som en ny ændringsanmodning, kunne vi implementere division logik:

offentlig klasse Division implementerer CalculatorOperation {privat dobbelt til venstre; privat dobbelt ret; privat dobbelt resultat // constructor, getters and setters @Override public void perform () {if (right! = 0) {result = left / right; }}}

Og endelig vores Lommeregner klasse behøver ikke at implementere ny logik, da vi introducerer nye operatører:

public class Calculator {public void calculate (CalculatorOperation operation) {if (operation == null) {throw new InvalidParameterException ("Kan ikke udføre operation"); } operation.perform (); }} 

På den måde er klassen lukket til ændring men åben til en udvidelse.

3. Konklusion

I denne vejledning har vi lært, hvad der er OCP pr. Definition, og derefter uddybet denne definition. Vi så et eksempel på en simpel lommeregnerapplikation, der var mangelfuld i designet. Endelig gjorde vi designet godt ved at lade det overholde OCP.

Som altid er koden tilgængelig på GitHub.