Паттерн "Стратегия"
Стратегия – это паттерн проектирования, который определяет семейство схожих алгоритмов и помещает каждый из них в собственный класс, после чего алгоритмы можно взаимозаменять прямо во время исполнения программы
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;
}
}
Паттерн "Наблюдатель"
Наблюдатель – это паттерн проектирования, который создает механизм подписки, позволяющий одним объектам следить и реагировать на события, происходящие в других объектах
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;
}
Паттерн State
// Example.java
public class Example {
public static void main(String[] args) {
Car car2 = new Car();
// Обращение к методам происходит через первоначальное получение состояния
car2.getState().go();
// start car
car2.getState().start();
car2.getState().go();
car2.getState().lock();
State state = car2.getState();
if (state != null) {
state.stop();
}
car2.getState().lock();
}
}
// Car.java
import exercise.state.impl.LockedState;
public class Car {
// Должна быть связь с классом состояния
private State state;
public Car() {
this.state = new LockedState(this);
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
}
// State.java
// Интерфейс состояния, каждое состояние должно реализовать его
public interface State {
void go();
void stop();
void start();
void lock();
}
// DriveState.java
public class DriveState implements State {
// Должна быть связь с классом Car
private Car car;
public DriveState(Car car) {
this.car = car;
}
@Override
public void go() {
System.out.println("I have gone yet.");
}
@Override
public void stop() {
System.out.println("Okey, I will stop");
this.car.setState(new StartState(this.car));
}
@Override
public void start() {
System.out.println("I have been started.");
}
@Override
public void lock() {
System.out.println("I can't be locked.");
}
}
// StartState.java
public class StartState implements State {
private Car car;
public StartState(Car car) {
this.car = car;
}
@Override
public void go() {
Car car = this.car;
car.setState(new DriveState(car));
System.out.println("Okey, I can do it.");
}
@Override
public void stop() {
System.out.println("Okey, I can be stopped.");
}
@Override
public void start() {
System.out.println("I have been started.");
}
@Override
public void lock() {
Car c = this.car;
c.setState(new LockedState(c));
System.out.println("Car has been locked.");
}
}
// LockedState.java
public class LockedState implements State {
private Car car;
public LockedState(Car car) {
this.car = car;
}
@Override
public void go() {
System.out.println("I have been locked. I can't go before you do not start me.");
}
@Override
public void stop() {
System.out.println("I have been locked. It means that I stopped.");
}
@Override
public void start() {
Car c = this.car;
c.setState(new StartState(c));
System.out.println("Car has been started.");
}
@Override
public void lock() {
System.out.println("Car has been locked.");
}
}
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.