Menu
Coddy logo textTech

Паттерн Factory

Часть раздела Объектно-ориентированное программирование путешествия по Java на Coddy. Урок 66 из 87.

Factory Pattern — это порождающий шаблон проектирования, который делегирует создание объектов отдельному методу или классу. Вместо того чтобы напрямую использовать new в своём коде, вы просите фабрику создавать объекты за вас. Это особенно полезно, когда у вас есть несколько связанных классов, использующих общий интерфейс или родительский класс.

Рассмотрим систему notification, которая может отправлять электронные письма, SMS или push-уведомления. Без фабрики вашему коду пришлось бы знать о каждом concrete class:

// Без Factory — клиент должен знать все конкретные классы
Notification notification;
if (type.equals("email")) {
    notification = new EmailNotification();
} else if (type.equals("sms")) {
    notification = new SMSNotification();
}

С помощью шаблона Factory вы централизуете эту логику создания:

public interface Notification {
    void send(String message);
}

public class EmailNotification implements Notification {
    public void send(String message) {
        System.out.println("Email: " + message);
    }
}

public class SMSNotification implements Notification {
    public void send(String message) {
        System.out.println("SMS: " + message);
    }
}

public class NotificationFactory {
    public static Notification create(String type) {
        if (type.equals("email")) {
            return new EmailNotification();
        } else if (type.equals("sms")) {
            return new SMSNotification();
        }
        return null;
    }
}

Теперь код client стал чище и не зависит от concrete classes:

Notification notification = NotificationFactory.create("email");
notification.send("Hello!");  // Вывод: Email: Hello!

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

challenge icon

Задание

Легко

Давайте создадим систему рисования фигур с использованием шаблона Factory! Вместо того чтобы создавать объекты фигур напрямую по всему коду, вы централизуете логику создания в фабрике, которая создаёт разные типы фигур на основе простого строкового идентификатора.

Вы организуете код в четырёх файлах:

  • Shape.java: Define интерфейс под названием Shape, который служит общим контрактом для всех фигур. Ваш интерфейс должен declare единственный method draw(), который ничего не возвращает, а выводит информацию о рисуемой фигуре.
  • Shapes.java: Create три classes, которые implement ваш интерфейс Shape:

    Circle — его method draw() должен выводить Drawing a Circle

    Rectangle — его method draw() должен выводить Drawing a Rectangle

    Triangle — его method draw() должен выводить Drawing a Triangle

  • ShapeFactory.java: Create класс Factory, который отвечает за создание фигур. Ваш ShapeFactory должен иметь статический method createShape(String type), возвращающий Shape. В зависимости от параметра type:
    • Если type equals "circle", return новый Circle
    • Если type equals "rectangle", return новый Rectangle
    • Если type equals "triangle", return новый Triangle
    • Для любого другого значения return null
  • Main.java: Объедините вашу фабричную систему! Вы получите два входных значения: два типа фигур (оба String).

    Для каждого входного значения используйте ваш ShapeFactory, чтобы create фигуру, и сохраните её в переменной Shape. Если Factory возвращает допустимую фигуру (не null), вызовите её method draw(). Если она возвращает null, выведите Unknown shape: [type], где [type] — предоставленное входное значение.

    Обработайте оба входных значения по порядку, каждое в своей строке вывода.

Вы получите два входных значения по порядку: первый тип фигуры (String) и второй тип фигуры (String).

Обратите внимание, что ваш класс Main никогда не использует new Circle() или new Rectangle() напрямую. Он знает только об интерфейсе Shape и просит Factory create объекты. В этом заключается сила шаблона Factory: код client отделён от concrete classes!

Попробуйте сами

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Прочитать два типа фигур
        String type1 = scanner.nextLine();
        String type2 = scanner.nextLine();
        
        // TODO: Используйте ShapeFactory для создания первой фигуры
        // Если фигура не null, вызовите draw()
        // If the shape is null, print "Unknown shape: [type]"
        
        // TODO: Сделайте то же самое для второй фигуры
        
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Java