Презентация на тему: Принципы SOLID

Принципы SOLID
Что такое SOLID
Принципы объектно-ориентированного дизайна
Single responsibility Принцип единственной обязанности
Пример нарушения принципа SRP
Как исправить
Но...
Open-closed Принцип открытости/закрытости
Пример нарушения OCP
Как исправить
Как исправить(продолжение)
Liskov substitution Принцип подстановки Барбары Лисков
Принципы SOLID
Принципы SOLID
Принципы SOLID
Замещение
Нарушение принципа LSP
Square-rectangle problem
Класс Rectangle
Класс Square
В чем же проблема?
Как исправить
Interface segregation Принцип разделения интерфейса
“Толстый” интерфейс
Пример нарушения ISP
Как исправить
Dependency inversion Принцип инверсии зависимостей
Принципы SOLID
Принципы SOLID
Внедрение зависимостей через конструктор (Constructor Injection)
Принципы SOLID
1/31
Средняя оценка: 4.7/5 (всего оценок: 79)
Код скопирован в буфер обмена
Скачать (408 Кб)
1

Первый слайд презентации: Принципы SOLID

5 принципов объектно-ориентированного программирования, описывающих архитектуру программного обеспечения

Изображение слайда
2

Слайд 2: Что такое SOLID

SOLID - это аббревиатура пяти основных принципов дизайна классов в объектно-ориентированном проектировании. Аббревиатура была введена Робертом Мартином в начале 2000-х. Рекомендую почитать: Чистый код. Роберт Мартин

Изображение слайда
3

Слайд 3: Принципы объектно-ориентированного дизайна

Изображение слайда
4

Слайд 4: Single responsibility Принцип единственной обязанности

Класс или модуль должны иметь одну и только одну причину измениться. Все члены этого класса должны быть связаны одной целью. Наш класс не должен быть похож на швейцарский нож, в котором при изменении одного из членов нужно изменять весь инструментарий.

Изображение слайда
5

Слайд 5: Пример нарушения принципа SRP

class Order { public void calculate(){... } public void addItem(Product product){... } public List<Product> getItems(){... } ... public void load(){... } public void save(){... } public void print(){... } }

Изображение слайда
6

Слайд 6: Как исправить

class Order { public void calculate(); public void addItem(Product product){... } public List<Product> getItems(){... } } class OrderRepository { public Order load(int orderId){... } public void save(Order order){... } } class OrderPrintManager { public void print(Order order){... } }

Изображение слайда
7

Слайд 7: Но

Существует, например, паттерн Active Record, который нарушает принцип SRP Active Record может быть успешно использован в небольших проектах с простой бизнес-логикой. ActiveRecord post = Post.newRecord(); post.setData("title", "Happy Java Programming"); post.setData("body", "Java programming is fun."); post.create();

Изображение слайда
8

Слайд 8: Open-closed Принцип открытости/закрытости

Объекты проектирования (классы, функции, модули и т.д.) должны быть открыты для расширения, но закрыты для модификации. Это означает, что новое поведение должно добавляться только добавлением новых сущностей, а не изменением старых.

Изображение слайда
9

Слайд 9: Пример нарушения OCP

class MessageSender { … public void send(String message, MessageType type) { if(type == MessageType.SMS) sendSMS(msg); else if(type == MessageType.EMAIL) sendEmail(msg); } }

Изображение слайда
10

Слайд 10: Как исправить

Воспользуемся паттерном “Стратегия” interface SendingStrategy { void send(String message); } class MessageSender { private SendingStrategy strategy; public MessageSender(SendingStrategy strategy) { this.strategy = strategy; } public void send(String message) { this.strategy.send(message); } }

Изображение слайда
11

Слайд 11: Как исправить(продолжение)

Конкретные стратегии отправки class EmailSendingStrategy implements SendingStrategy { @Override public void send(String message) { System.out.println("Sending Email: " + message); } } class SMSSendingStrategy implements SendingStrategy { @Override public void send(String message) { System.out.println("Sending SMS: " + message); } }

Изображение слайда
12

Слайд 12: Liskov substitution Принцип подстановки Барбары Лисков

Данный принцип гласит, что «вы должны иметь возможность использовать любой производный класс вместо родительского класса и вести себя с ним таким же образом без внесения изменений».

Изображение слайда
13

Слайд 13

Изображение слайда
14

Слайд 14

Изображение слайда
15

Слайд 15

Изображение слайда
16

Слайд 16: Замещение

T S Объекты типа T могут быть замещены объектами типа S без каких-либо изменений желательных свойств этой программы

Изображение слайда
17

Слайд 17: Нарушение принципа LSP

Circle-ellipse problem Square-rectangle problem

Изображение слайда
18

Слайд 18: Square-rectangle problem

Является ли класс Квадрат подклассом класса Прямоугольник? Rectangle Square ?

Изображение слайда
19

Слайд 19: Класс Rectangle

class Rectangle { private double width; private double height; public double getWidth() { return width; } public void setWidth(double width) { this.width = width; } public double getHeight() { return height; } public void setHeight(double height) { this.height = height; } public String toString() { return this.width + "x" + this.height; } }

Изображение слайда
20

Слайд 20: Класс Square

class Square extends Rectangle { public void setWidth(double width) { this.setSide(width); } public void setHeight(double height) { this.setSide(height); } public void setSide(double side) { super.setWidth(side); super.setHeight(side); } }

Изображение слайда
21

Слайд 21: В чем же проблема?

public class LiskovViolation { public static void main(String[] args) { Rectangle rectangle = new Square(); rectangle.setWidth(10); System.out.println(rectangle); // 10.0x10.0 rectangle.setHeight(20); System.out.println(rectangle); // 20.0x20.0 !!!! Should be 10.0x20.0 } }

Изображение слайда
22

Слайд 22: Как исправить

Если использовать концепцию неизменяемого объекта (immutable object), то принцип не будет нарушаться. Необходимо убрать возможность изменения объекта после его создания.

Изображение слайда
23

Слайд 23: Interface segregation Принцип разделения интерфейса

Слишком «толстые» интерфейсы необходимо разделять на более маленькие и специфические, чтобы клиенты маленьких интерфейсов знали только о методах, которые необходимы им в работе.

Изображение слайда
24

Слайд 24: Толстый” интерфейс

Если среди методов интерфейса можно выделить группы методов, которые нужны определенным пользователям интерфейса, то скорее всего интерфейс “толстый”. Такой интерфейс нужно разбить на более мелкие, которые будут выражать потребности конкретной группы пользователей интерфейса.

Изображение слайда
25

Слайд 25: Пример нарушения ISP

interface Person { void goToWork(); void withdrawSalary(); void eat(); } Если мы захотим сделать реализацию, в которой единственным необходимым методом будет eat() придется реализовывать и все остальные методы

Изображение слайда
26

Слайд 26: Как исправить

public interface Person { void eat(); } public interface Worker { void goToWork(); void withdrawSalary(); }

Изображение слайда
27

Слайд 27: Dependency inversion Принцип инверсии зависимостей

Все взаимосвязи в программе должны поддерживаться с помощью абстракных классом или интерфейсов. Данный принцип гласит, что, во-первых, классы высокого уровня не должны зависеть от низкоуровневых классов. При этом оба должны зависеть от абстракций. Во-вторых, абстракции не должны зависеть от деталей, но детали должны зависеть от абстракций.

Изображение слайда
28

Слайд 28

Изображение слайда
29

Слайд 29

Изображение слайда
30

Слайд 30: Внедрение зависимостей через конструктор (Constructor Injection)

Изображение слайда
31

Последний слайд презентации: Принципы SOLID

Изображение слайда