logo

SOLID Принципи Java

В Java, ТВЪРДИ принципи са обектно-ориентиран подход, който се прилага за проектиране на софтуерна структура. Концептуализира се от Робърт К. Мартин (известен също като чичо Боб). Тези пет принципа промениха света на обектно-ориентираното програмиране и също промениха начина на писане на софтуер. Той също така гарантира, че софтуерът е модулен, лесен за разбиране, отстраняване на грешки и рефакторинг. В този раздел ще обсъдим SOLID принципи в Java с подходящ пример .

Думата SOLID е акроним за:

  • Принцип на единната отговорност (SRP)
  • Принцип отворено-затворено (OCP)
  • Принцип на заместване на Лисков (LSP)
  • Принцип на разделяне на интерфейса (ISP)
  • Принцип на инверсия на зависимостта (DIP)
SOLID Принципи Java

Нека обясним принципите един по един в детайли.

Принцип на единната отговорност

Принципът на единната отговорност гласи това всеки Java клас трябва да изпълнява една единствена функция . Внедряването на множество функции в един клас смесва кода и ако е необходима някаква модификация, може да засегне целия клас. Той прецизира кода и кодът може лесно да се поддържа. Нека разберем принципа на единичната отговорност чрез пример.

Да предположим, Студент е клас с три метода, а именно printDetails(),calculatePercentage(), и addStudent(). Следователно класът Student има три отговорности за отпечатване на подробности за учениците, изчисляване на проценти и база данни. Като използваме принципа на единичната отговорност, можем да разделим тези функционалности в три отделни класа, за да изпълним целта на принципа.

ctc пълна форма

Студент.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 } } 

Горният кодов фрагмент нарушава принципа на единичната отговорност. За да постигнем целта на принципа, трябва да внедрим отделен клас, който изпълнява само една функционалност.

Студент.java

 public class Student { public void addStudent(); { //functionality of the method } } 

PrintStudentDetails.java

int към char
 public class PrintStudentDetails { public void printDetails(); { //functionality of the method } } 

Процент.java

 public class Percentage { public void calculatePercentage(); { //functionality of the method } } 

Следователно постигнахме целта на принципа на единната отговорност, като разделихме функционалността на три отделни класа.

Принцип отворено-затворено

Приложението или модулът съдържа методите, функциите, променливите и т.н. Принципът отворено-затворено гласи, че според новите изисквания модулът трябва да е отворен за разширение, но затворен за модификация. Разширението ни позволява да внедрим нова функционалност към модула. Нека разберем принципа чрез пример.

Да предположим, VehicleInfo е клас и има метода vehicleNumber() който връща номера на автомобила.

VehicleInfo.java

 public class VehicleInfo { public double vehicleNumber(Vehicle vcl) { if (vcl instanceof Car) { return vcl.getNumber(); if (vcl instanceof Bike) { return vcl.getNumber(); } } 

Ако искаме да добавим друг подклас на име Truck, просто добавяме още един оператор if, който нарушава принципа отворено-затворено. Единственият начин да добавите подкласа и да постигнете целта на принципа, като замените vehicleNumber() метод, както сме показали по-долу.

VehicleInfo.java

 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(); } 

По същия начин можем да добавим още превозни средства, като направим друг подклас, който се разширява от класа на превозното средство. подходът няма да повлияе на съществуващото приложение.

урок за javafx

Принцип на заместване на Лисков

Принципът на заместване на Лисков (LSP) е въведен от Варвара Лискова . Прилага се към наследяването по такъв начин, че производните класове трябва да бъдат напълно заместими за техните базови класове . С други думи, ако клас A е подтип на клас B, тогава трябва да можем да заменим B с A, без да прекъсваме поведението на програмата.

Той разширява принципа отваряне-затваряне и също така се фокусира върху поведението на суперклас и неговите подтипове. Трябва да проектираме класовете, за да запазим собствеността, освен ако нямаме сериозна причина да направим друго. Нека разберем принципа чрез пример.

Студент.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); } } 

Горните класове нарушават принципа на заместване на Liskov, тъй като класът Student BMI има допълнителни ограничения, т.е. височина и тегло, които трябва да бъдат еднакви. Следователно класът Student (базов клас) не може да бъде заменен от клас StudentBMI (производен клас).

Следователно заместването на класа Student с клас Student BMI може да доведе до неочаквано поведение.

Принцип на разделяне на интерфейса

Принципът гласи, че по-големите интерфейси се разделят на по-малки. Тъй като класовете за изпълнение използват само методите, които са необходими. Не трябва да принуждаваме клиента да използва методите, които не иска да използва.

Целта на принципа на разделяне на интерфейса е подобна на принципа на единичната отговорност. Нека разберем принципа чрез пример.

SOLID Принципи Java

Да предположим, че сме създали интерфейс с име Преобразуване с три метода intToDouble(), intToChar(), и charToString() .

 public interface Conversion { public void intToDouble(); public void intToChar(); public void charToString(); } 

Горният интерфейс има три метода. Ако искаме да използваме само метод intToChar(), нямаме избор да приложим единичния метод. За да преодолеем проблема, принципът ни позволява да разделим интерфейса на три отделни.

 public interface ConvertIntToDouble { public void intToDouble(); } public interface ConvertIntToChar { public void intToChar(); } public interface ConvertCharToString { public void charToString(); } 

Сега можем да използваме само необходимия метод. Да предположим, че искаме да преобразуваме цялото число в двойно и символ в низ, тогава ще използваме само методите intToDouble() и charToString().

 public class DataTypeConversion implements ConvertIntToDouble, ConvertCharToString { public void intToDouble() { //conversion logic } public void charToString() { //conversion logic } } 

Принцип на инверсия на зависимостта

Принципът гласи, че трябва да използваме абстракция (абстрактни класове и интерфейси) вместо конкретни реализации. Модулите на високо ниво не трябва да зависят от модула на ниско ниво, но и двата трябва да зависят от абстракцията. Защото абстракцията не зависи от детайла, а детайлът зависи от абстракцията. Той отделя софтуера. Нека разберем принципа чрез пример.

 public class WindowsMachine { //functionality } 

Струва си, ако нямаме клавиатура и мишка, за да работим на Windows. За да разрешим този проблем, създаваме конструктор на класа и добавяме екземплярите на клавиатурата и монитора. След добавяне на екземплярите, класът изглежда по следния начин:

 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 } } 

Вече можем да работим на Windows машина с помощта на клавиатура и мишка. Но все още сме изправени пред проблема. Тъй като сме свързали плътно трите класа заедно, като използваме новата ключова дума. Трудно е да тествате машината за клас Windows.

За да направим кода слабо свързан, отделяме WindowsMachine от клавиатурата, като използваме интерфейса на клавиатурата и тази ключова дума.

Keyboard.java

конвертиране на char в int 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; } } 

В горния код използвахме инжектирането на зависимост, за да добавим зависимостта от клавиатурата в класа WindowsMachine. Затова отделихме класовете.

SOLID Принципи Java

Защо трябва да използваме принципите на SOLID?

  • Той намалява зависимостите, така че блок от код може да бъде променен, без да се засягат другите кодови блокове.
  • Принципите, предназначени да направят дизайна по-лесен, разбираем.
  • Чрез използването на принципите системата може да се поддържа, тества, мащабира и може да се използва повторно.
  • Избягва лошия дизайн на софтуера.

Следващият път, когато проектирате софтуер, имайте предвид тези пет принципа. Чрез прилагането на тези принципи кодът ще бъде много по-ясен, тестван и използваем.