na Jawie, SOLIDNE zasady to podejście obiektowe stosowane do projektowania struktury oprogramowania. Jest to konceptualizowane przez Roberta C. Martina (znany również jako wujek Bob). Te pięć zasad zmieniło świat programowania obiektowego, a także zmieniło sposób pisania oprogramowania. Zapewnia również, że oprogramowanie jest modułowe, łatwe do zrozumienia, debugowania i refaktoryzacji. W tej części omówimy Zasady SOLID w Javie z właściwym przykładem .
wyjaśnić niezależność danych
Akronim słowa SOLID oznacza:
- Zasada pojedynczej odpowiedzialności (SRP)
- Zasada otwartego-zamkniętego (OCP)
- Zasada substytucji Liskowa (LSP)
- Zasada segregacji interfejsu (ISP)
- Zasada inwersji zależności (DIP)
Wyjaśnijmy szczegółowo zasady jedna po drugiej.
Zasada pojedynczej odpowiedzialności
Stanowi to zasada pojedynczej odpowiedzialności każda klasa Java musi wykonywać jedną funkcjonalność . Implementacja wielu funkcjonalności w jednej klasie powoduje zmieszanie kodu i ewentualne modyfikacje, które mogą mieć wpływ na całą klasę. Precyzuje kod, a kod można łatwo utrzymać. Przyjrzyjmy się zasadzie pojedynczej odpowiedzialności na przykładzie.
Przypuszczać, Student jest klasą posiadającą trzy metody, a mianowicie printDetails(), obliczPercentage(), I dodajStudenta(). Dlatego klasa Student ma trzy zadania: drukowanie szczegółowych informacji o uczniach, obliczanie wartości procentowych i tworzenie bazy danych. Stosując zasadę pojedynczej odpowiedzialności, możemy podzielić te funkcjonalności na trzy oddzielne klasy, aby spełnić cel tej zasady.
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 } }
Powyższy fragment kodu narusza zasadę pojedynczej odpowiedzialności. Aby osiągnąć cel zasady należy zaimplementować osobną klasę realizującą tylko jedną funkcjonalność.
Student.java
public class Student { public void addStudent(); { //functionality of the method } }
WydrukujStudentDetails.java
public class PrintStudentDetails { public void printDetails(); { //functionality of the method } }
Procent.java
public class Percentage { public void calculatePercentage(); { //functionality of the method } }
Zatem osiągnęliśmy cel zasady pojedynczej odpowiedzialności poprzez rozdzielenie funkcjonalności na trzy odrębne klasy.
Zasada otwarte-zamknięte
Aplikacja lub moduł encjiuje metody, funkcje, zmienne itp. Zasada open-closed mówi, że zgodnie z nowymi wymaganiami moduł powinien być otwarty na rozbudowę, ale zamknięty na modyfikację. Rozszerzenie pozwala na dodanie nowej funkcjonalności do modułu. Rozumiemy zasadę na przykładzie.
Przypuszczać, Informacje o pojeździe jest klasą i zawiera metodę numer pojazdu() która zwraca numer pojazdu.
Informacje o pojeździe.java
public class VehicleInfo { public double vehicleNumber(Vehicle vcl) { if (vcl instanceof Car) { return vcl.getNumber(); if (vcl instanceof Bike) { return vcl.getNumber(); } }
Jeśli chcemy dodać kolejną podklasę o nazwie Truck, po prostu dodajemy jeszcze jedną instrukcję if, która narusza zasadę open-closed. Jedynym sposobem na dodanie podklasy i osiągnięcie celu zasady jest zastąpienie numer pojazdu() sposób, jak pokazaliśmy poniżej.
Informacje o pojeździe.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(); }
Podobnie możemy dodać więcej pojazdów, tworząc kolejną podklasę wykraczającą poza klasę pojazdów. podejście to nie miałoby wpływu na istniejącą aplikację.
Zasada substytucji Liskowa
Zasada substytucji Liskowa (LSP) została wprowadzona przez Barbara Liskow . Dotyczy to dziedziczenia w ten sposób, że klasy pochodne muszą być całkowicie substytucyjne dla swoich klas podstawowych . Innymi słowy, jeśli klasa A jest podtypem klasy B, to powinniśmy móc zastąpić B przez A bez zakłócania działania programu.
Java czyta plik linia po linii
Rozszerza zasadę otwórz-zamknij, a także skupia się na zachowaniu nadklasy i jej podtypów. Powinniśmy zaprojektować klasy tak, aby chronić własność, chyba że mamy mocny powód, aby postąpić inaczej. Rozumiemy zasadę na przykładzie.
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); } }
Powyższe klasy naruszają zasadę podstawienia Liskowa, ponieważ klasa StudentBMI ma dodatkowe ograniczenia tj. wzrost i waga, które muszą być takie same. W związku z tym klasy Student (klasa bazowa) nie można zastąpić klasą StudentBMI (klasa pochodna).
Dlatego zastąpienie klasy Student klasą StudentBMI może skutkować nieoczekiwanym zachowaniem.
Zasada segregacji interfejsów
Zasada głosi, że większe interfejsy dzielą się na mniejsze. Ponieważ klasy implementacyjne wykorzystują tylko te metody, które są wymagane. Nie powinniśmy na siłę zmuszać klienta do korzystania z metod, z których nie chce skorzystać.
Cel zasady segregacji interfejsów jest podobny do zasady pojedynczej odpowiedzialności. Rozumiemy zasadę na przykładzie.
Załóżmy, że stworzyliśmy interfejs o nazwie Konwersja mając trzy metody intToDouble(), intToChar(), I charToString() .
public interface Conversion { public void intToDouble(); public void intToChar(); public void charToString(); }
Powyższy interfejs ma trzy metody. Jeśli chcemy użyć tylko metody intToChar(), nie mamy wyboru, czy zaimplementować pojedynczą metodę. Aby przezwyciężyć ten problem, zasada pozwala nam podzielić interfejs na trzy osobne.
public interface ConvertIntToDouble { public void intToDouble(); } public interface ConvertIntToChar { public void intToChar(); } public interface ConvertCharToString { public void charToString(); }
Teraz możemy zastosować tylko tę metodę, która jest wymagana. Załóżmy, że chcemy zamienić liczbę całkowitą na double i znak na string, wówczas skorzystamy tylko z metod intToDouble() I charToString().
public class DataTypeConversion implements ConvertIntToDouble, ConvertCharToString { public void intToDouble() { //conversion logic } public void charToString() { //conversion logic } }
Zasada inwersji zależności
Zasada mówi, że zamiast konkretnych implementacji musimy używać abstrakcji (klas abstrakcyjnych i interfejsów). Moduły wysokiego poziomu nie powinny zależeć od modułu niskiego poziomu, ale oba powinny zależeć od abstrakcji. Bo abstrakcja nie zależy od szczegółu, ale szczegół zależy od abstrakcji. Oddziela oprogramowanie. Rozumiemy zasadę na przykładzie.
public class WindowsMachine { //functionality }
Warto, jeśli nie mamy klawiatury i myszki, aby pracować na Windowsie. Aby rozwiązać ten problem, tworzymy konstruktor klasy i dodajemy instancje klawiatury i monitora. Po dodaniu instancji klasa wygląda następująco:
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 } }
Teraz możemy pracować na komputerze z systemem Windows za pomocą klawiatury i myszy. Ale nadal stoimy przed problemem. Ponieważ ściśle połączyliśmy ze sobą trzy klasy, używając słowa kluczowego new. Trudno jest przetestować klasową maszynę z systemem Windows.
Aby kod był luźno powiązany, odłączamy WindowsMachine od klawiatury za pomocą interfejsu Keyboard i tego słowa kluczowego.
inaczej Java
Klawiatura.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; } }
W powyższym kodzie użyliśmy wstrzykiwania zależności, aby dodać zależność klawiatury w klasie WindowsMachine. Dlatego rozdzieliliśmy klasy.
Dlaczego powinniśmy stosować zasady SOLID?
- Zmniejsza zależności, dzięki czemu można zmienić blok kodu bez wpływu na inne bloki kodu.
- Zasady mające na celu uczynienie projektowania łatwiejszym, zrozumiałym.
- Dzięki zastosowaniu tych zasad system jest łatwy w utrzymaniu, testowalny, skalowalny i nadaje się do ponownego użycia.
- Pozwala uniknąć złego projektu oprogramowania.
Następnym razem, gdy będziesz projektować oprogramowanie, pamiętaj o tych pięciu zasadach. Stosując te zasady, kod będzie znacznie bardziej przejrzysty, testowalny i zbędny.