I Java, SOLIDA principer är ett objektorienterat tillvägagångssätt som tillämpas på mjukvarustrukturdesign. Det konceptualiseras av Robert C. Martin (även känd som Uncle Bob). Dessa fem principer har förändrat världen av objektorienterad programmering, och även förändrat sättet att skriva mjukvara. Det säkerställer också att programvaran är modulär, lätt att förstå, felsöka och återställa. I det här avsnittet kommer vi att diskutera SOLIDA principer i Java med rätt exempel .
Ordet SOLID akronym för:
- Single Responsibility Principle (SRP)
- Öppen-stängd princip (OCP)
- Liskov Substitution Principle (LSP)
- Interface Segregation Principle (ISP)
- Dependency Inversion Principle (DIP)
Låt oss förklara principerna en efter en i detalj.
Principen om ett enda ansvar
Det säger principen om ett enda ansvar varje Java-klass måste utföra en enda funktionalitet . Implementering av flera funktioner i en enda klass blandar ihop koden och om någon modifiering krävs kan det påverka hela klassen. Den preciserar koden och koden kan lätt underhållas. Låt oss förstå principen om ett enda ansvar genom ett exempel.
Anta, Studerande är en klass som har tre metoder nämligen printDetails(), calculatePercentage(), och addStudent(). Studentklassen har därför tre ansvarsområden för att skriva ut information om elever, beräkna procentsatser och databas. Genom att använda principen om ett enda ansvar kan vi dela upp dessa funktioner i tre separata klasser för att uppfylla målet med principen.
Student.java
public class Student { public void printDetails(); { //functionality of the method } pubic void calculatePercentage(); { //functionality of the method } public void addStudent(); { //functionality of the method } }
Ovanstående kodavsnitt bryter mot principen om ett enda ansvar. För att uppnå målet med principen bör vi implementera en separat klass som endast utför en enda funktionalitet.
Student.java
public class Student { public void addStudent(); { //functionality of the method } }
PrintStudentDetails.java
public class PrintStudentDetails { public void printDetails(); { //functionality of the method } }
Procent.java
public class Percentage { public void calculatePercentage(); { //functionality of the method } }
Därför har vi uppnått målet med principen om ett enda ansvar genom att dela upp funktionaliteten i tre separata klasser.
Öppet-stängt princip
Applikationen eller modulen består av metoder, funktioner, variabler etc. Öppet-stängt-principen säger att enligt nya krav modulen ska vara öppen för förlängning men stängd för modifiering. Tillägget tillåter oss att implementera ny funktionalitet i modulen. Låt oss förstå principen genom ett exempel.
Anta, VehicleInfo är en klass och den har metoden fordonsnummer() som returnerar fordonsnumret.
VehicleInfo.java
public class VehicleInfo { public double vehicleNumber(Vehicle vcl) { if (vcl instanceof Car) { return vcl.getNumber(); if (vcl instanceof Bike) { return vcl.getNumber(); } }
Om vi vill lägga till ytterligare en underklass med namnet Truck, lägger vi helt enkelt till en till if-sats som bryter mot öppet-stängt-principen. Det enda sättet att lägga till underklassen och uppnå det principiella målet genom att åsidosätta fordonsnummer() metod, som vi har visat nedan.
VehicleInfo.java
shilpa shetty ålder
public class VehicleInfo { public double vehicleNumber() { //functionality } } public class Car extends VehicleInfo { public double vehicleNumber() { return this.getValue(); } public class Car extends Truck { public double vehicleNumber() { return this.getValue(); }
På samma sätt kan vi lägga till fler fordon genom att göra en annan underklass som sträcker sig från fordonsklassen. tillvägagångssättet skulle inte påverka den befintliga tillämpningen.
Liskov Substitutionsprincip
Liskov Substitution Principle (LSP) introducerades av Barbara Liskov . Det gäller arv på ett sådant sätt att härledda klasser måste vara helt utbytbara mot sina basklasser . Med andra ord, om klass A är en undertyp av klass B, så borde vi kunna ersätta B med A utan att avbryta programmets beteende.
Den utökar principen om öppen-stäng och fokuserar också på beteendet hos en superklass och dess undertyper. Vi bör utforma klasserna för att bevara fastigheten om vi inte har en stark anledning att göra något annat. Låt oss förstå principen genom ett exempel.
Student.java
public class Student { private double height; private double weight; public void setHeight(double h) { height = h; } public void setWeight(double w) { weight= w; } ... } public class StudentBMI extends Student { public void setHeight(double h) { super.setHeight(h); super.setWeight(w); } public void setWeight(double h) { super.setHeight(h); super.setWeight(w); } }
Ovanstående klasser bröt mot Liskov-substitutionsprincipen eftersom StudentBMI-klassen har extra begränsningar, dvs längd och vikt som måste vara samma. Därför kan Studentklassen (basklassen) inte ersättas med StudentBMI-klassen (härledd klass).
Att ersätta klassen Student med StudentBMI-klassen kan därför resultera i oväntat beteende.
Gränssnittssegregationsprincip
Principen säger att de större gränssnitten delas upp i mindre. Eftersom implementeringsklasserna endast använder de metoder som krävs. Vi ska inte tvinga klienten att använda de metoder som de inte vill använda.
Målet med gränssnittssegregationsprincipen liknar principen om ett enda ansvar. Låt oss förstå principen genom ett exempel.
Anta att vi har skapat ett gränssnitt som heter Omvandling har tre metoder intToDouble(), intToChar(), och charToString() .
public interface Conversion { public void intToDouble(); public void intToChar(); public void charToString(); }
Ovanstående gränssnitt har tre metoder. Om vi bara vill använda en metod intToChar() har vi inget val att implementera den enda metoden. För att övervinna problemet tillåter principen oss att dela upp gränssnittet i tre separata.
public interface ConvertIntToDouble { public void intToDouble(); } public interface ConvertIntToChar { public void intToChar(); } public interface ConvertCharToString { public void charToString(); }
Nu kan vi bara använda den metod som krävs. Anta att vi vill konvertera heltal till dubbelt och tecken till sträng, då använder vi bara metoderna intToDouble() och charToString().
public class DataTypeConversion implements ConvertIntToDouble, ConvertCharToString { public void intToDouble() { //conversion logic } public void charToString() { //conversion logic } }
Beroendeinversionsprincipen
Principen säger att vi måste använda abstraktion (abstrakta klasser och gränssnitt) istället för konkreta implementeringar. Högnivåmoduler bör inte bero på lågnivåmodulen utan båda bör bero på abstraktionen. Eftersom abstraktionen inte beror på detaljer utan detaljen beror på abstraktion. Det kopplar bort programvaran. Låt oss förstå principen genom ett exempel.
public class WindowsMachine { //functionality }
Det är värt, om vi inte har tangentbord och mus att fungera på Windows. För att lösa detta problem skapar vi en konstruktor för klassen och lägger till instanserna av tangentbordet och bildskärmen. Efter att ha lagt till instanserna ser klassen ut så här:
public class WindowsMachine { public final keyboard; public final monitor; public WindowsMachine() { monitor = new monitor(); //instance of monitor class keyboard = new keyboard(); //instance of keyboard class } }
Nu kan vi arbeta på Windows-maskinen med hjälp av tangentbord och mus. Men vi står fortfarande inför problemet. Eftersom vi har kopplat ihop de tre klasserna hårt genom att använda det nya nyckelordet. Det är svårt att testa klassens Windows-maskin.
För att göra koden löst kopplad kopplar vi bort WindowsMachine från tangentbordet genom att använda tangentbordsgränssnittet och detta nyckelord.
Keyboard.java
public interface Keyboard { //functionality }
WindowsMachine.java
public class WindowsMachine { private final Keyboard keyboard; private final Monitor monitor; public WindowsMachine(Keyboard keyboard, Monitor monitor) { this.keyboard = keyboard; this.monitor = monitor; } }
I ovanstående kod har vi använt beroendeinjektionen för att lägga till tangentbordsberoendet i WindowsMachine-klassen. Därför har vi frikopplat klasserna.
Varför ska vi använda SOLID principer?
- Det minskar beroenden så att ett kodblock kan ändras utan att påverka de andra kodblocken.
- Principerna syftar till att göra design lättare, begriplig.
- Genom att använda principerna är systemet underhållbart, testbart, skalbart och återanvändbart.
- Det undviker programvarans dåliga design.
Nästa gång när du designar programvara, tänk på dessa fem principer. Genom att tillämpa dessa principer blir koden mycket mer tydlig, testbar och förbrukbar.