Рубрики
Без рубрики

SOLID: Принцип Единой Ответственности

Качество кода является одной из ключевых составляющих разработки программного обеспечения, тем не менее, также является одним из основных факторов… С тегами java, ооп, программирование, архитектура.

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

Принципы SOLID жизненно важны в объектно-ориентированном программировании (ООП), поскольку они позволяют вам писать программы, которые можно поддерживать, расширять и тестировать. Тем не менее, очень часто можно найти опытных и неопытных разработчиков, которые никогда о них не слышали. Конечно, я не был исключением из правила. Моя страсть к разработке программного обеспечения началась в 2004 году с разработки простых программ сложения и вычитания на языке Pascal. На протяжении многих лет я изучал несколько языков, таких как C, C++, Visual Basic, Visual FoxPro и т.д. В 2008 году я изучил Java и парадигму ООП, но только в 2014 году мой коллега одолжил мне книгу Роберта К. Мартина “Чистый код”. Из этой книги я узнал о стандартах кодирования и лучших практиках, но самое главное, я узнал о принципах SOLID.

Прежде чем прочитать “Чистый код”, прошло 6 лет, в течение которых я развивался профессионально, не зная о принципах SOLID. Честно говоря, существует огромная разница между качеством моих программ до и после их изучения. Самое известное улучшение заключается в том, что теперь я могу писать приложения, которые легко поддерживать и тестировать.

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

ТВЕРДЫЕ Принципы

Принципы S.O.L.I.D. – это 5 пяти основополагающих принципов объектно-ориентированного программирования. Они были разработаны Робертом К. Мартином (дядя Боб) в 2000 году. Основная цель SOLID principles – устранить плохие практики в разработке программного обеспечения, а также помочь разработчику написать поддерживаемый, масштабируемый и тестируемый код.

Твердые принципы подтверждаются:

  • S Принцип единой ответственности.
  • Принцип O pen/Closed.
  • L Принцип замещения Лискова
  • Принцип разделения интерфейсов Ввода|вывода. D
  • Принцип инверсии зависимостей.

Термин ТВЕРДЫЙ это аббревиатура от этих пяти принципов.

Принцип Единой Ответственности

Принцип единой ответственности (SRP) означает, что класс, метод или модуль должны иметь только одну ответственность. Другими словами, у него должна быть только одна причина для изменения. Иногда мы создаем классы, методы или модули, которые имеют слишком много обязанностей одновременно. Например, иногда у вас может быть класс, который имеет бизнес-логику, логику сохранения, регистр журнала, все в одном классе. Это является нарушением SRP, потому что класс пытается делать много вещей одновременно, и изменение одной из этих обязанностей означает, что все остальные обязанности также будут затронуты.

Основной целью SRP является разделение обязанностей и сокращение объема при внесении изменений.

Давайте посмотрим на следующий пример:

package com.yourregulardeveloper.entities;

import java.math.BigDecimal;
import java.util.List;

public class Client {
    private String clientId;
    private String name;
    private String lastName;

    public Client(String clientId, String name, String lastName) {
        this.clientId = clientId;
        this.name = name;
        this.lastName = lastName;
    }

    /**
     * Calculates the subtotal invoice.
     * @param articles         List of articles bought by the client.
     * @return                 Invoice subtotal.
     */
    public BigDecimal calculateSubTotalInvoice(List
articles){ return articles .stream() .map(article -> article.getUnitPrice() .multiply(new BigDecimal(article.getAmount))) .reduce(BigDecimal.ZERO, BigDecimal::add); } /** * Calculates the total invoice. * @param subtotal Invoice subtotal. * @param taxPercentage Tax percentage. * @return Total invoice. */ public BigDecimal calculateTotalInvoice(BigDecimal subtotal, BigDecimal taxPercentage){ return subtotal.add(subtotal.multiply(taxPercentage)); } public String getClientId() { return this.clientId; } public void setClientId(String clientId) { this.clientId = clientId; } public String getName() { return this.name; } public void setName(String name) { this.name = name; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }

Класс “Клиент” нарушает SRP, поскольку он несет более одной ответственности, а именно:

  • Обработка клиентской сущности на протяжении всего жизненного цикла приложения. Эта ответственность возлагается на атрибуты и методы, связанные с информацией клиента.
  • Калькулятор итоговых сумм счетов-фактур. Эта ответственность возлагается на методы calculate SubTotal Invoice() и calculateTotalInvoice().

Основной и единственной обязанностью класса “Клиент” должна быть обработка сущности клиента. Плохой дизайн наложил на класс вторую ответственность. Чтобы решить эту проблему с плохим дизайном, мы могли бы внедрить SRP и разделить обязанности на два разных класса.

package com.yourregulardeveloper.entities;

public class Client {
    private String clientId;
    private String name;
    private String lastName;

    public Client(String clientId, String name, String lastName) {
        this.clientId = clientId;
        this.name = name;
        this.lastName = lastName;
    }

    public String getClientId() {
        return this.clientId;
    }

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}
package com.yourregulardeveloper.invoice;

import java.math.BigDecimal;
import java.util.List;

public class InvoiceCalculator {

    /**
     * Calculates the subtotal invoice.
     * @param articles         List of articles bought by the client.
     * @return                 Invoice subtotal.
     */
    public BigDecimal calculateSubTotalInvoice(List
articles){ return articles .stream() .map(article -> article.getUnitPrice() .multiply(new BigDecimal(article.getAmount))) .reduce(BigDecimal.ZERO, BigDecimal::add); } /** * Calculates the total invoice. * @param subtotal Invoice subtotal. * @param taxPercentage Tax percentage. * @return Total invoice. */ public BigDecimal calculateTotalInvoice(BigDecimal subtotal, BigDecimal taxPercentage){ return subtotal.add(subtotal.multiply(taxPercentage)); } }

Теперь у нас есть класс “Клиент” и класс “InvoiceCalculator”. У каждого из этих классов есть только одна ответственность или только одна причина измениться. SPR позволил классу “Client” нести ответственность только за обработку объекта client, а классу “InvoiceCalculator” – только за вычисление итоговых значений счета-фактуры. Оба класса легче читать, поддерживать и тестировать.

Принцип единой ответственности в отношении методов

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

SRP позволяет писать методы, которые несут только одну ответственность, не заботясь о ее размере, просто заботясь о том, чтобы у метода была одна причина для изменения.

Принцип единой ответственности плохая практика

Иногда плохое внедрение SRP может быть контрпродуктивным. Например, если реализация SRP преувеличена, вы можете в конечном итоге писать классы только с одним методом, что может быть неправильным. Мы должны помнить, что SRP диктует, что единица кодирования (метод/класс/модуль) должна иметь только одну причину для изменения. Мы также должны помнить, что правильная реализация SPR позволяет нам группировать различные единицы кода с одной ответственностью. Это не диктует количество методов в классе или количество строк в методе.

SRP помогает нам разделять проблемы и обязанности и является ключом к написанию масштабируемого, поддерживаемого и тестируемого кода. Это позволяет нам устранить плохие практики, такие как: реализация классов и методов, которые делают много вещей одновременно.

Если вы хотите узнать больше о SRP, вы можете заглянуть в Блог дяди Боба .

В следующем посте мы поговорим о принципе “Открыто/закрыто”.

Вы можете следить за мной в Твиттере Твиттер .

Оригинал: “https://dev.to/victorpinzon1988eng/solid-single-responsibility-principle-48an”