Принципы SOLID — презентация
logo
Принципы 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

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

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

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

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

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

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

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

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

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

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

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

Слайд 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: Но

Существует, например, паттерн 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: Open-closed Принцип открытости/закрытости

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

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

Слайд 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: Как исправить

Воспользуемся паттерном “Стратегия” 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); } }

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

Конкретные стратегии отправки 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: Liskov substitution Принцип подстановки Барбары Лисков

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

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

Слайд 13

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

Слайд 14

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

Слайд 15

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

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

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

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

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

Circle-ellipse problem Square-rectangle problem

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

Слайд 18: Square-rectangle problem

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

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

Слайд 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: Класс 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: В чем же проблема?

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: Как исправить

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Слайд 28

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

Слайд 29

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

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

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

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

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

Похожие презентации