〰️
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. Лабораторно упражнение 4

Factory Method

Factory Method е модел на проектиране на обекти, който осигурява интерфейс за създаване на обекти в базов клас, но позволява на подкласовете да променят вида на обектите, които ще бъдат създадени.

Проблема

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

След известно време приложението ви става доста популярно. Всеки ден получавате десетки заявки от фирми за морски превози за включване на морска логистика в приложението.

Понастоящем по-голямата част от кода е съсредоточена в един клас. Добавянето в приложението би изисквало извършване на промени в цялата програма. Освен това, ако по-късно решите да добавите друг вид транспорт към приложението, вероятно ще трябва да направите всички тези промени отново.

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

Решението

Factory Method предполага, че замествате преките повиквания за изграждане на обекти (с помощта на оператора) с повиквания към специален фабричен метод. Не се притеснявайте: обектите все още се създават чрез оператора, но той се нарича от вътре в фабричния метод. Обектите, връщани по фабрично метод, често се обозначават като продукти.

На пръв поглед тази промяна може да изглежда безсмислена: току-що преместихме конструкторното обаждане от една част на програмата в друга. Помислете обаче за това: сега можете да превъзмогнете фабричния метод в подклас и да промените класа продукти, които се създават по метода.

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

Например, както и класовете трябва да внедрят интерфейса, който декларира метод, наречен . Всеки клас прилага този метод по различен начин: камионите доставят товари по суша, корабите доставят товари по море. Фабричният метод в класа връща предметите на товарния автомобил, докато фабричният метод в класа връща корабите.

Кодът, който използва фабричния метод (често наричан клиентски код), не вижда разлика между действителните продукти, върнати от различни подкласове. Клиентът третира всички продукти като абстрактни . Клиентът знае, че всички транспортни обекти се предполага, че имат метода, но точно как работи не е важно за клиента.

Използване

1. Използвайте Фабричния метод, когато не знаете предварително точните типове и зависимости на обектите, с които трябва да работи кодът ви.

2. Използвайте Фабричния метод, когато искате да предоставите на потребителите на вашата библиотека или рамка начин за разширяване на вътрешните му компоненти.

3. Използвайте Фабричния метод, когато искате да запишете системни ресурси, като използвате повторно съществуващите обекти, вместо да ги възстановите всеки път.

Имплементация

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

  2. Добавете фабричeн метод в класа на създателя. Типът връщане на метода трябва да съответства на общия продуктов интерфейс.

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

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

  5. Ако има твърде много типове продукти и няма смисъл да създавате подкласове за всички тях, можете да използвате повторно параметъра за управление от базовия клас в подкласове.

  6. Ако след всички екстракции методът на базовата фабрика е станал празен, можете да го направите абстрактен. Ако е останало нещо, можете да го направите поведение по подразбиране на метода.

Положителни страни
Отрицателни страни

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

Кодът може да стане по-сложен, тъй като трябва да се въведат много нови подкласове за прилагане на модела. Най-добрият сценарий е, когато въвеждате шаблона в съществуваща йерархия от класове създатели.

Единен отговорен принцип. Можете да преместите кода за създаване на продукта на едно място в програмата, което прави кода по-лесен за поддръжка.

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

Пример

Създайте приложение за изпращане на нотификации по SMS, Email и Push (изкачащи)

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

public interface Notification {
    void notifyUser();
}

Интерфейса ще се наследи от класовете доставящи нотификации

public class SMSNotification implements Notification {
 
    @Override
    public void notifyUser()
    {
        System.out.println("Sending an SMS notification");
    }
}
public class EmailNotification implements Notification {
 
    @Override
    public void notifyUser()
    {
        System.out.println("Sending an e-mail notification");
    }
}
public class PushNotification implements Notification {
 
    @Override
    public void notifyUser()
    {
        System.out.println("Sending a push notification");
    }
}

Създаването на обектите от конкретните класове ще минава през фактори клас

public class NotificationFactory {
    public Notification createNotification(String channel)
    {
        if (channel == null || channel.isEmpty())
            return null;
        switch (channel) {
        case "SMS":
            return new SMSNotification();
        case "EMAIL":
            return new EmailNotification();
        case "PUSH":
            return new PushNotification();
        default:
            throw new IllegalArgumentException("Unknown channel "+channel);
        }
    }
}

Самото създаване на обекти минава през фактори метода по следния начин

public class Main {
    public static void main(String[] args)
    {
        NotificationFactory notificationFactory = new NotificationFactory();
        Notification notification = notificationFactory.createNotification("SMS");
        notification.notifyUser();
    }
}
PreviousЛабораторно упражнение 4NextAbstract Factory

Last updated 2 years ago

Was this helpful?