〰️
Programming with Java
  • Програмиране с JAVA
  • Обектно-ориентирано програмиране - 1 част
    • Лабораторно упражнение 1
      • Основи на програмирането с Java за начинаещи‎
        • Oбщи термини в Java
        • Основни характеристики на JAVA‎
        • Инсталиране на JDK
        • Инсталиране на Intellij
      • Първа програма в Java
      • Системен изход в JAVA
      • Дефиниране на променливи
      • Примитивни типове данни
      • Оператори
      • If-else
      • Switch-Case
      • For loop
      • While loop
      • Do-while loop
      • Continue
      • Break
      • Задачи
    • Лабораторно упражнение 2
      • Клас
      • Обект
      • Ключова дума new
      • Запазена дума static
      • Конвенции за именуване в Java
      • Wrapper Class
      • Сравняване на
      • Нуждата Wrapper Class
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 3
      • Наследяване
      • this и super
      • Модификатори за достъп
      • Капсулиране
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 4
      • Проследяване на грешки
      • Оценяване на изрази
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 5
      • Полиморфизъм
      • Абстрактен клас
      • Интерфейс
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 6
      • Разлика между Абстрактен клас и Интерфейс
        • Разлика 1
        • Разлика 2
        • Разлика 3
        • Разлика 4
        • Разлика 5
        • Разлика 6
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 7
      • String
      • Enum
      • Обработка на изключения
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 8
      • Генерични класове
      • Генеричен метод
      • Параметри на типа в Java Generics
      • Предимства на генериците
      • Генериците работят само с референтни типове
    • Лабораторно упражнение 9
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 10
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 11
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 12
      • Упражнения за извънаудиторна заетост
    • Лабораторно упражнение 13
      • Упражнения за извънаудиторна заетост
      • Упражнения за извънаудиторна заетост
  • Обектно-ориентирано програмиране - 2 част
    • Лабораторно упражнение 1
      • SRP - Single Responsibility Principle
        • Задачи
      • OCP - Open-Closed Principle
        • Задачи
    • Лабораторно упражнение 2
      • LSP - Liskov Substitution Principle
        • Задачи
      • ISP - Interface Segregation Principle
        • Задачи
      • DI - Dependency Inversion Principle
        • Задачи
    • Лабораторно упражнение 3
      • Singleton
        • Задачи
      • Builder
        • Задачи
    • Лабораторно упражнение 4
      • Factory Method
      • Abstract Factory
      • Задачи
    • Лабораторно упражнение 5
    • Лабораторно упражнение 6
      • Decorator
      • Bridge
        • Композиция
      • Задачи
    • Лабораторно упражнение 7
      • Adapter
      • Задачи
    • Лабораторно упражнение 8
      • Composite
      • Proxy
      • Задачи
    • Лабораторно упражнение 9
    • Лабораторно упражнение 10
      • Visitor
      • State
      • Задачи
    • Лабораторно упражнение 11
      • Observer
      • Задачи
    • Лабораторно упражнение 12
      • Chain of Responsibility
      • Command
      • Задачи
    • Лабораторно упражнение 13
  • Интернет технологии 2023
    • Лабораторно упражнение 1
      • HTTP протокол
        • Синтаксис на URL
        • HTTP съобщения
        • Методи за HTTP заявка
        • Кодове за състояние на HTTP отговор
      • Postman
        • Изпращане на заявка с Postman
        • Получаване на отговор
      • Задачи за работа с Postman
    • Лабораторно упражнение 2
      • Работа с Tomcat
      • Maven
      • Създаване на Maven проект в IntelliJ Ultimate Edition
      • Създаване на Maven проект в IntelliJ Community Edition
      • Създаване на Maven проект в Eclipse IDE
    • Лабораторно упражнение 3
      • Java Servlets
      • Жизнен цикъл на сървлета
      • Създаване на сървлети
      • Задачи за създаване на сървлети
    • Лабораторно упражнение 4
      • Extensible Markup Language
      • Java Architecture for XML Binding
      • JavaScript Object Notation
      • Задачи
    • Лабораторно упражнение 5
    • Лабораторно упражнение 6
      • Spring Boot
      • Създаване на Spring boot проект
      • Структура на Spring Boot проект
        • Файлът pom.xml
        • Main клас в Spring Boot
        • Управление на конфигурацията с application.properties
      • Задача
    • Лабораторно упражнение 7
      • Комуникационен поток и CRUD операции
      • ResponseEntity
      • Избрани анотации
      • Задача
    • Лабораторно упражнение 8
      • Lombok
      • Data transfer object (DTO)
      • Обработване на изключения в Spring Boot приложение
        • Клас Optional<T>
      • Валидиране на данните от заявката
      • Задачи
    • Лабораторно упражнение 9-10
      • Конфигуриране на PostgreSQL DB
      • Jakarta Persistence анотации
      • Repository слой
      • Задачи
    • Лабораторно упражнение 11
      • Проследяване на сесии
      • Филтри и FilterChain
      • Spring Security
        • Добавяне на Spring Security в Spring Boot приложение
        • Конфигуриране на филтри
        • Удостоверяване със Spring Security
        • Защита на метод със Spring Security
      • Задача
    • Лабораторно упражнение 12
      • JSON Web Token
      • Защита с помощта на JWT
      • Задача
    • Лабораторно упражнение 13
  • Програмиране за мобилни и Интернет устройства
    • Лабораторно упражнение 1
      • Задачи
    • Лабораторно упражнение 2
      • Среда за разработване
        • Създаване на проект
        • Структора на проект
        • Виртуално устройство с Android OS
      • Задача
    • Лабораторно упражнение 3
      • Activity
      • Layout
        • XML описание
      • Задача
    • Лабораторно упражнение 4
      • Activity Lifecycle
      • Intent
      • Слушатели на събитията и методи за обратно извикване
      • Задача
    • Лабораторно упражнение 5
      • Слушатели на събитията и методи за обратно извикване
      • Задача
    • Лабораторно упражнение 6
      • Фрагменти
      • DialogFragment
      • Задача
    • Лабораторно упражнение 7
      • Примери
        • BaseAdapter
        • ArrayAdapter
        • Custom ArrayAdapter
      • RecyclerView
        • Пример
      • CardView
      • Задача
    • Лабораторно упражнение 8
      • Runnable
      • HandlerThread
      • ThreadPoolExecutor
      • Задача
    • Лабораторно упражнение 9
      • Задача
      • Задача
      • Пример
  • Интернет Технологии
    • Лабораторно упражнение 1
      • Инсталиране и настройка на необходимата среда за работа в упражненията
      • Maven
      • Създаване на Maven проект в Eclipse IDE
      • Създаване на Maven проект в IntelliJ
      • Работа с Tomcat
      • Задача
    • Лабораторно упражнение 2
      • HTML форми
      • Cascading Style Sheets (CSS)
        • CSS селектори
        • Някои CSS свойства
      • Задача
    • Лабораторно упражнение 3
      • Java Servlets
      • Жизнен цикъл на сървлета
      • Създаване на сървлети
      • Задачи
    • Лабораторно упражнение 4
      • Java Server Pages технология. Същност и детайли
      • Пренасочване между Servlet и JSP
      • Задачи
    • Лабораторно упражение 5
      • Build pattern
      • JavaBean
      • Задачи
    • Лабораторно упражение 6
      • Проследяване на сесии
      • Управление на бисквитки (Cookies)
      • Задачи
    • Лабораторно упражнение 7
      • Проследяване на сесии
      • Управление на бисквитки (Cookies)
      • Servlet Filter
      • Задачи
    • Лабораторно упражнение 8
      • Servlet Filter
      • Прихващане на грешки
      • Задачи
    • Лабораторно упражнение 9
      • Extensible Markup Language
      • JavaScript Object Notation
        • Fetch
      • Задача
    • Лабораторно упражнение 10
      • Java Architecture for XML Binding
      • Задачи
Powered by GitBook
On this page

Was this helpful?

  1. Обектно-ориентирано програмиране - 2 част
  2. Лабораторно упражнение 1

SRP - Single Responsibility Principle

Единна отговорност

Този принцип гласи, че един елемент трябва да има само една отговорност. Освен това тя следва да има само една причина да се промени, тази причина е промяна в изискването, какво се изисква от този елемент да изпълнява.

Този принцип помага да и се раздели по-добър софтуер, като ни позволява по лесно да:

  1. Тестваме – Клас с една отговорност ще има много по-малко тестови случаи.

  2. По-малко връзки – По-малко функционалност в един клас ще има по-малко зависимости.

  3. Организация – По-малките, добре организирани класове са по-лесни за разбиране от монолитните.

Да започнем от следния пример, най-вероятно сте чували принципа: Една функция трябва да прави едно и само едно нещо. Ние използваме този принцип, когато рефакторираме (преработка на код, с цел да се подобри неговото качество, без да се промени крайния резултат) големи функции в по-малки функции; използва се на най-ниските нива.

Въпреки това, вярвам че се е случвало да пишете подобен код:

public static void calculateSum() {
     System.out.println("Enter the Two numbers for addtion: ");  
     Scanner readInput = new Scanner(System.in);  
     
     int a = readInput.nextInt();  
     int b = readInput.nextInt();
     int sum = a + b;
     
     System.out.println("The sum of numbers is: "+sum);     
}

Така написана функцията, дали може да получава числа от, файл, база данни, фруга функция, сензоро?

Според вас тази функция изпълнява ли повече от едно нещо?

SOLID принципа за единна отговорност (SRP), много прилича на принципа по горе но е и различен. Докато принципа "Една функция, една отговорност" е приложим на ниско ниво, по колкото по нагоре се отива толкова по трудно става разпознаването на отговорностите.

Всеки клас може да съдържа повече от един метод или поле, в тази ситуация не може да се приложи директно подхода както при функциите, а трябва да се мисли за средата в която това обединение от методи и променливи ще намери приложение.

Може да се разбере този принцип, като се разгледат симптомите/начините по които се нарушава.

СИМПТОМ 1: СЛУЧАЙНО ДУБЛИРАНЕ

Като пример може да разгледаме приложение за заплати в което присъства клас Employee, тои има три метода: calculatePay(), reportHours() и save().

Employee.java
public class Employee {
     public void calculatePay() {
          //код на метода
     }
     public void reportHours() {
          //код на метода
     }
     public void save() {
          //код на метода
     }
}

Метода calculatePay() изчислява заплатата необходима за счетоводния отдел

Метода reportHours() е специфичен и се отнася към отдела за човешки ресурси

Метода save() се отнася до администраторите на Базата даннищ

Да предположим, че функцията calculatePay() и reportHours() споделят общ алгоритъм за изчисляване на часове без извънреден труд.

Как бихте организирали когда си?

Логично е да поставим този алгоритъм във функция, предимството ще е че няма да се дублира код, с името regularHours()

Обединяването на тези 3 метода в един клас може да доведе до следното:

Свързване на счетоводния отдел, човешки ресурси, администраторите помежду им. Това обединение може да може накара действията на счетоводния отдел да повлияят на нещо, от който отдел човешки ресурси зависи.

Например, нека разгледаме един клас, за да представим една проста книга:

public class Book {

    private String name;
    private String author;
    private String text;

    //constructor, getters and setters
}

В този код съхраняваме името, автора и текста, свързани с екземпляр на Книга.

Нека сега добавим няколко метода за обработка на текста:

public class Book {

    private String name;
    private String author;
    private String text;

    //constructor, getters and setters

    // methods that directly relate to the book properties
    public String replaceWordInText(String word){
        return text.replaceAll(word, text);
    }

    public boolean isWordInText(String word){
        return text.contains(word);
    }
}

Сега нашият клас Book работи добре и можем да съхраняваме толкова книги, колкото ни харесва в нашето приложение.

Но каква полза е съхраняването на информацията, ако не можем да изведем текста в нашата конзола и да я прочетем?

Нека оставим предпазливоста на страна и да добавим метод за печат:

public class Book {
    //...

    void printTextToConsole(){
        // our code for formatting and printing the text
    }
}

Този метод ще има достъп до системните ресурси за извеждане, което ще добави нова зависимост в него. Освен да съхранява информацията за книгата, класа знае и къде да я презентира.

Това какво виждате нарушава принципа на единната отговорност, който очертахме по-рано.

За да оправим бъркотията си, трябва да внедрим отделен клас, който се занимава само с отпечатване на нашите текстове:

public class BookPrinter {

    // methods for outputting text
    void printTextToConsole(String text){
        //our code for formatting and printing the text
    }

    void printTextToAnotherMedium(String text){
        // code for writing to any other location..
    }
}

Не само сме разработили клас, който обслужва Book на нейните задължения за печат, но и можем да използваме нашия клас BookPrinter, за да изпратим текста си на други медии.

Независимо дали става дума за имейл, сеч, или нещо друго, имаме отделен клас, посветен на тази грижа.

Трикът за внедряване на SRP в нашия софтуер е познаването на отговорността на всеки клас.

Следвайки принципа SRP, нашите класове ще се придържат към една функционалност. Техните методи и данни ще бъдат загрижени с една ясна цел. Това означава високо кохерентност, както и устойчивост на промени, които заедно намаляват грешките.

Въпреки че името на принципа е саморазяснително, можем да видим колко лесно е да се приложи неправилно. Уверете се, че ще разграничите отговорността на всеки клас при разработването на проект и обърнете допълнително внимание на кохерентността.

PreviousЛабораторно упражнение 1NextЗадачи

Last updated 2 years ago

Was this helpful?