Разделы презентаций


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

Содержание

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

Слайды и текст этой презентации

Слайд 1Принципы объектно-ориентированного дизайна
SOLID:
Single responsibility
Open-closed
Liskov substitution
Interface segregation
Dependency inversion

Принципы объектно-ориентированного дизайнаSOLID:Single responsibilityOpen-closedLiskov substitutionInterface segregationDependency inversion

Слайд 2Что такое SOLID
SOLID - это аббревиатура пяти основных принципов дизайна

классов в объектно-ориентированном проектировании.
Аббревиатура была введена Робертом Мартином в начале

2000-х.

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

Слайд 3Основные принципы
Single responsibility - Принцип единственной обязанности
Open-closed - Принцип открытости/закрытости
Liskov

substitution - Принцип подстановки Барбары Лисков
Interface segregation - Принцип разделения

интерфейса
Dependency inversion - Принцип инверсии зависимостей

Основные принципыSingle responsibility - Принцип единственной обязанностиOpen-closed - Принцип открытости/закрытостиLiskov substitution - Принцип подстановки Барбары ЛисковInterface segregation

Слайд 4Single responsibility Принцип единственной обязанности
Класс или модуль должны иметь одну и

только одну причину измениться.

Single responsibility Принцип единственной обязанностиКласс или модуль должны иметь одну и только одну причину измениться.

Слайд 5Пример нарушения принципа SRP
class Order
{
public void calculate(){ ...

}
public void addItem(Product product){ ... }
public

List getItems(){ ... }
...
public void load(){ ... }
public void save(){ ... }
public void print(){ ... }
}
Пример нарушения принципа SRPclass Order{  public void calculate(){ ... }  public void addItem(Product product){ ...

Слайд 6Как исправить
class Order
{
public void calculate();
public void

addItem(Product product){ ... }
public List getItems(){ ... }
}


class OrderRepository
{
public Order load(int orderId){ ... }
public void save(Order order){ ... }
}

class OrderPrintManager
{
public void print(Order order){ ... }
}
Как исправитьclass Order{  public void calculate();  public void addItem(Product product){ ... }  public List

Слайд 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();
Но...Существует, например, паттерн Active Record, который нарушает принцип SRPActive Record может быть успешно использован в небольших проектах

Слайд 8Open-closed Принцип открытости/закрытости
Объекты проектирования (классы, функции, модули и т.д.) должны

быть открыты для расширения, но закрыты для модификации.
Это означает, что

новое поведение должно добавляться только добавлением новых сущностей, а не изменением старых.
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);
}
}
Пример нарушения OCPclass MessageSender {  …  public void send(String message, MessageType type){

Слайд 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);
}

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

Слайд 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);
}

}
Как исправить(продолжение)Конкретные стратегии отправкиclass EmailSendingStrategy implements SendingStrategy {  @Override  public void send(String message) {

Слайд 12Liskov substitution Принцип подстановки Барбары Лисков
Роберт С. Мартин определил этот

принцип так:

Функции, которые используют базовый тип, должны иметь

возможность использовать подтипы базового типа не зная об этом.
Liskov substitution  Принцип подстановки Барбары ЛисковРоберт С. Мартин определил этот принцип так:  Функции, которые используют

Слайд 13Замещение
T
S
Объекты типа T могут быть замещены объектами типа S без

каких-либо изменений желательных свойств этой программы

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

Слайд 14Нарушение принципа LSP
Circle-ellipse problem
Square-rectangle problem

Нарушение принципа LSPCircle-ellipse problemSquare-rectangle problem

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

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

Слайд 16Класс 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;
}
}

Класс Rectangleclass Rectangle {  private double width;  private double height;  public double getWidth() {

Слайд 17Класс 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);
}

}
Класс Squareclass Square extends Rectangle { public void setWidth(double width) {  this.setSide(width); } public void setHeight(double

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

}

В чем же проблема?public class LiskovViolation {  public static void main(String[] args) {   Rectangle

Слайд 19Как исправить
Если использовать концепцию неизменяемого объекта (immutable object), то принцип

не будет нарушаться.
Необходимо убрать возможность изменения объекта после его создания.

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

Слайд 20Interface segregation Принцип разделения интерфейса
Слишком «толстые» интерфейсы необходимо разделять на

более маленькие и специфические, чтобы клиенты маленьких интерфейсов знали только

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

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

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

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

Слайд 22Пример нарушения ISP
interface Person {
void goToWork();
void

withdrawSalary();
void eat();
}
Если мы захотим сделать реализацию, в которой

единственным необходимым методом будет eat() придется реализовывать и все остальные методы
Пример нарушения ISPinterface Person {  void goToWork();  void withdrawSalary();  void eat();}Если мы захотим сделать

Слайд 23Как исправить
public interface Person {
void eat();
}

public interface Worker

{
void goToWork();
void withdrawSalary();
}

Как исправитьpublic interface Person {  void eat();}public interface Worker {  void goToWork();  void withdrawSalary();}

Слайд 24Dependency inversion Принцип инверсии зависимостей
Все взаимосвязи в программе должны поддерживаться

с помощью абстракных классом или интерфейсов.

Dependency inversion  Принцип инверсии зависимостейВсе взаимосвязи в программе должны поддерживаться с помощью абстракных классом или интерфейсов.

Слайд 25Нарушение принципа DIP
public class Crawler {
public void saveHtmlDocument()

{
DomBasedHtmlParser parser = new DomBasedHtmlParser();

HtmlDocument document = parser.parseUrl("http://example.com/");
save(document, "index.html");
}

public void save(HtmlDocument htmlDocument, String pageName) {
// сохранение документа в файл
}
}

Экземпляр класса парсер создается внутри метода saveHtmlDocument() и не использует интерфейс, что делает невозможным использования другой реализации парсера и затрудняет тестирование.

Нарушение принципа DIPpublic class Crawler {  public void saveHtmlDocument() {   DomBasedHtmlParser parser = new

Слайд 26Как исправить. Вариант 1
public class Crawler {
private HtmlParser

parser;

public Crawler(HtmlParser parser) {
this.parser

= parser;
}

public void saveHtmlDocument() {
HtmlDocument document = parser.parseUrl("http://example.com/");
save(document, "index.html");
}

public void save(HtmlDocument htmlDocument, String pageName) {
// сохранение документа в файл
}
}
Как исправить. Вариант 1public class Crawler {  private HtmlParser parser;  public Crawler(HtmlParser parser) {

Слайд 27Как исправить. Вариант 2
public class Crawler{
private HtmlParser parser

= ParserFactory.getHtmlParser();

public void saveHtmlDocument() {
HtmlDocument

document = parser.parseUrl("http://example.com/");
save(document, "index.html");
}

public void save(HtmlDocument htmlDocument, String pageName) {
// сохранение документа в файл
}
}
Как исправить. Вариант 2public class Crawler{  private HtmlParser parser = ParserFactory.getHtmlParser();  public void saveHtmlDocument() {

Обратная связь

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

Email: Нажмите что бы посмотреть 

Что такое TheSlide.ru?

Это сайт презентации, докладов, проектов в PowerPoint. Здесь удобно  хранить и делиться своими презентациями с другими пользователями.


Для правообладателей

Яндекс.Метрика