Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Паттерны (продолжение) Java: Основы ООП

Паттерн "Фабрика"

Фабрика - это паттерн проектирования, который определяет общий интерфейс для создания объектов, позволяя создавать тип выбираемых объектов


TransportFactory transportFactory = new TransportFactory();
Transport wagon = transportFactory.getTransport("wagon");
Transport ship = transportFactory.getTransport("ship");
List<Transport> transports = new ArrayList<>();
transports.add(wagon);
transports.add(ship);

for (Transport transport : transports) {
    transport.deliver();
}

Класс TransportFactory

public class TransportFactory {
    public static final String WAGON_NAME = "wagon";
    public static final String SHIP_NAME = "ship";

    public Transport getTransport(String name) {
        if (Object.equals(name, WAGON_NAME)) {
            return new Wagon();
        } else if (Object.equals(name, SHIP_NAME)) {
            return new Ship();
        }

        return null;
    }
}

Интерфейс Transport

public interface Transport {
    void deliver();
}

Классы Ship и Wagon

public class Ship implements Transport {
    public void deliver() {
        System.out.println("SHIP: I deliver an object");
    }
}
public class Wagon implements Transport {
    public void deliver() {
        System.out.println("WAGON: I deliver an object");
    }
}

Паттерн "Стратегия"

Стратегия – это паттерн проектирования, который определяет семейство схожих алгоритмов и помещает каждый из них в собственный класс, после чего алгоритмы можно взаимозаменять прямо во время исполнения программы

double price = 100.83
Discounter christmasDiscounter = new ChristmasDiscounter();
Discounter eightMarchDiscounter = new EightMarchDiscounter();
List<Discounter> discounters = new ArrayList<>();

discounters.add(christmasDiscounter);
discounters.add(eightMarchDiscounter);

for (Discounter discounter : discounters) {
    if (discounter.checkCondition()) {
        discounter.applyDiscount(price);
    }
}

Интерфейс Discounter

public interface Discounter {
    double applyDiscount(double price);
    boolean checkCondition();
}

Классы стратегий

public class ChristmasDiscounter implements Discounter {

    @Override
    public double applyDiscount(double price) {
        System.out.println("ChristmasDiscounter has been applied");
        return price * 0.5;
    }

    @Override
    public boolean checkCondition() {
        Calendar calendar = Calendar.getInstance();
        long currentDate = calendar.getTimeInMillis();
        calendar.set(Calendar.MONTH, 11);
        calendar.set(Calendar.DAY_OF_MONTH, 25);
        long christmasDay = calendar.getTimeInMillis();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        long startChristmasDiscountDay = calendar.getTimeInMillis();

        return currentDate >= startChristmasDiscountDay && currentDate <= christmasDay;
    }
}
public class EightMarchDiscounter implements Discounter {

    @Override
    public double applyDiscount(double price) {
        System.out.println("EightMarchDiscounter has been applied");
        return price * 0.75;
    }

    @Override
    public boolean checkCondition() {
        Calendar calendar = Calendar.getInstance();
        long currentDate = calendar.getTimeInMillis();
        calendar.set(Calendar.MONTH, 2);
        calendar.set(Calendar.DAY_OF_MONTH, 8);
        long eightMarchDay = calendar.getTimeInMillis();

        calendar.set(Calendar.DAY_OF_MONTH, 1);
        long startEightMarcDiscountDay = calendar.getTimeInMillis();

        return currentDate >= startEightMarcDiscountDay && currentDate <= eightMarchDay;
    }
}

Паттерн "Прототип"

Прототип – это паттерн проектирования, который позволяет копировать объекты, не вдаваясь в подробности их реализации

Bmw bmw = new Bmw();
bmw.setTurboModeOn(true);
bmw.setName("BMW 320i");
bmw.setMaxSpeed(260);

Car bmw2 = bmw.clone();
System.out.println(bmw2);

Kia kia = new Kia();
kia.setMaxSpeed(230);
kia.setBlindZonesControl(true);


Car kia2 = kia.clone();
System.out.println(kia2);

Интерфейс Car

public interface Car {
    Car clone();
}

Классы Bmw и Kia

@Getter
@Setter
@ToString
public class Bmw implements Car {
    private int maxSpeed;
    private String name;
    private boolean isTurboModeOn;

    @Override
    public Car clone() {
        Bmw bmw = new Bmw();
        bmw.setMaxSpeed(this.getMaxSpeed());
        bmw.setIsTurboModeOn(this.isTurboModeOn());
        bmw.setName(this.getName());

        return bmw;
    }
}
@Getter
@Setter
@ToString
public class Kia implements Car {
    private int maxSpeed;
    private boolean isBlindZoneControl;

    @Override
    public Kia clone() {
        Kia kia = new Kia();
        kia.setBlindZonesControl(this.isBlindZoneControl);
        kia.setMaxSpeed(this.getMaxSpeed());

        return kia;
    }
}

Паттерн "Наблюдатель"

Наблюдатель – это паттерн проектирования, который создает механизм подписки, позволяющий одним объектам следить и реагировать на события, происходящие в других объектах

WeatherDataCenter weatherDataCenter = new WeatherDataCenter();
WeatherDataReceiver weatherDataReceiver = new WeatherDataReceiver();
weatherDataCenter.registerObserver(weatherDataReceiver);

WeatherData weatherData = new WeatherData();
weatherData.setTemperature(29.3);
weatherData.setPressure(760.3);

weatherDataCenter.notifyObservers(weatherData);

Классы WeatherDataCenter и WeatherDataReceiver

public class WeatherDataCenter implements Observable<WeatherData> {

    private List <Observer<WeatherData>> observers = new ArrayList<>();
    private WeatherData weatherData;

    @Override
    public void notifyObservers(WeatherData weatherData) {
        this.weatherData = weatherData;

        for (Observer observer : observers) {
            observer.update(weatherData);
        }
    }

    public void registerObserver(Observer<WeatherData> observer) {
        observers.add(observer);
    }

    public void removeObserver(Observer<WeatherData> observer) {
        observers.remove(observer);
    }
}
public class WeatherDataReceiver implements Observer<WeatherData> {

    private WeatherData weatherData;

    @Override
    public void update(WeatherData model) {
        this.weatherData = model;
        System.out.println(
            "Weather data has been updated: " + weatherData
        );
    }
}

Интерфейсы

public interface Observable<T> {
    void registerObserver(Observer<T> observer);
    void removeObserver(Observer<T> observer);
    void notifyObservers(T data);
}
public interface Observer<T> {
    void update(T model);
}

Класс WeatherData

@Getter
@Setter
@ToString
public class WeatherData {
    private double temperature;
    private double pressure;
}

Дополнительные материалы

  1. Паттерны без привязки к языку

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
от 25 000 ₸ в месяц
Разработка приложений на языке Java
10 месяцев
с нуля
Старт 21 ноября

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»
Изображение Тото

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