add Java sources
This commit is contained in:
parent
b6e1ec089c
commit
e815172862
Binary file not shown.
|
@ -1,12 +1,18 @@
|
|||
# Паттерны проектирования на языке D
|
||||
|
||||
Паттерны проектирования по книге [Head First. Паттерны проектирования](https://ftp.zhirov.kz/books/IT/%D0%9F%D0%B0%D1%82%D1%82%D0%B5%D1%80%D0%BD%D1%8B/Head%20First.%20%D0%9F%D0%B0%D1%82%D1%82%D0%B5%D1%80%D0%BD%D1%8B%20%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%20%28%D0%AD%D1%80%D0%B8%D0%BA%20%D0%A4%D1%80%D0%B8%D0%BC%D0%B5%D0%BD%2C%20%D0%AD%D0%BB%D0%B8%D0%B7%D0%B0%D0%B1%D0%B5%D1%82%20%D0%A0%D0%BE%D0%B1%D1%81%D0%BE%D0%BD%29%202022.pdf)
|
||||
Паттерны проектирования по книге [Head First. Паттерны проектирования](https://ftp.zhirov.kz/books/IT/%D0%9F%D0%B0%D1%82%D1%82%D0%B5%D1%80%D0%BD%D1%8B/Head%20First.%20%D0%9F%D0%B0%D1%82%D1%82%D0%B5%D1%80%D0%BD%D1%8B%20%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%20%28%D0%AD%D1%80%D0%B8%D0%BA%20%D0%A4%D1%80%D0%B8%D0%BC%D0%B5%D0%BD%2C%20%D0%AD%D0%BB%D0%B8%D0%B7%D0%B0%D0%B1%D0%B5%D1%82%20%D0%A0%D0%BE%D0%B1%D1%81%D0%BE%D0%BD%29%202022.pdf) ([исходный код на Java](Head-First-Design-Patterns-master.zip))
|
||||
|
||||
## Паттерны
|
||||
|
||||
### Поведенческие
|
||||
|
||||
1. [Стратегия](strategy/)
|
||||
2. [Наблюдатель](observer/)
|
||||
|
||||
### Структурные
|
||||
|
||||
1. [Декоратор](decorator/)
|
||||
|
||||
## Компиляция
|
||||
|
||||
```sh
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
# Декоратор
|
||||
|
||||
Декоратор — это структурный паттерн проектирования, который позволяет динамически добавлять объектам новую функциональность, оборачивая их в полезные «обёртки».
|
||||
|
||||
Типы декораторов соответствуют типам декорируемых компонентов (соответствие достигается посредством наследования или реализации интерфейса). Декораторы изменяют поведение компонентов, добавляя новую функциональность до и (или) после (или даже вместо) вызовов методов компонентов. Компонент может декорироваться любым количеством декораторов. Декораторы обычно прозрачны для клиентов компонента (если клиентский код не зависит от конкретного типа компонента).
|
||||
|
||||
## Принцип
|
||||
|
||||
- Согласно принципу открытости/закрытости системы должны проектироваться так, чтобы их закрытые компоненты были изолированы от новых расширений
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Наблюдатель — это поведенческий паттерн проектирования, который создаёт механизм подписки, позволяющий одним объектам следить и реагировать на события, происходящие в других объектах.
|
||||
|
||||
При использовании паттерна возможен как запрос, так и активная доставка данных от субъекта (запрос считается более "правильным").
|
||||
При использовании паттерна возможен как [запрос](request/), так и [активная доставка](delivery/) данных от субъекта (запрос считается более "правильным").
|
||||
|
||||
- **Активная доставка** - передача субъектом аргументов в качестве параметров функции `update()`
|
||||
- **Запрос** - подразумевает получение необходимых параметров от субъекта внутри функции `update()`
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
module observer.delivery.app;
|
||||
|
||||
import observer.delivery.weatherdata;
|
||||
import observer.delivery.currentconditionsdisplay;
|
||||
import observer.delivery.heatindexdisplay;
|
||||
import observer.delivery.forecastdisplay;
|
||||
import observer.delivery.statiscticdisplay;
|
||||
|
||||
void main()
|
||||
{
|
||||
WeatherData weatherData = new WeatherData();
|
||||
CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
|
||||
HeatIndexDisplay heatIndexDisplay = new HeatIndexDisplay(weatherData);
|
||||
ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
|
||||
StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
|
||||
|
||||
weatherData.setMeasurements(80, 65, 30.4f);
|
||||
weatherData.setMeasurements(82, 70, 29.2f);
|
||||
weatherData.removeObserver(forecastDisplay);
|
||||
weatherData.setMeasurements(78, 90, 29.2f);
|
||||
weatherData.setMeasurements(81, 72, 29.5f);
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
module observer.delivery.currentconditionsdisplay;
|
||||
|
||||
import observer.delivery.displayelement;
|
||||
import observer.delivery.observer;
|
||||
import observer.delivery.weatherdata;
|
||||
import std.stdio : writeln;
|
||||
import std.format : format;
|
||||
|
||||
class CurrentConditionsDisplay : Observer, DisplayElement
|
||||
{
|
||||
private:
|
||||
float temperature;
|
||||
float humidity;
|
||||
public:
|
||||
this(WeatherData weatherData)
|
||||
{
|
||||
weatherData.registerObserver(this);
|
||||
}
|
||||
|
||||
override void update(float temperature, float humidity, float pressure)
|
||||
{
|
||||
this.temperature = temperature;
|
||||
this.humidity = humidity;
|
||||
display();
|
||||
}
|
||||
|
||||
override void display()
|
||||
{
|
||||
writeln("Current conditions: %3.1f".format(temperature), "F degrees and %3.1f%% humidity".format(humidity));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
module observer.delivery.displayelement;
|
||||
|
||||
interface DisplayElement
|
||||
{
|
||||
void display();
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
module observer.delivery.forecastdisplay;
|
||||
|
||||
import observer.delivery.displayelement;
|
||||
import observer.delivery.observer;
|
||||
import observer.delivery.weatherdata;
|
||||
import std.stdio : write, writeln;
|
||||
import std.format : format;
|
||||
|
||||
class ForecastDisplay : Observer, DisplayElement
|
||||
{
|
||||
private:
|
||||
float currentPressure = 29.92f;
|
||||
float lastPressure;
|
||||
public:
|
||||
this(WeatherData weatherData)
|
||||
{
|
||||
weatherData.registerObserver(this);
|
||||
}
|
||||
|
||||
override void update(float temperature, float humidity, float pressure)
|
||||
{
|
||||
lastPressure = currentPressure;
|
||||
currentPressure = pressure;
|
||||
display();
|
||||
}
|
||||
|
||||
override void display()
|
||||
{
|
||||
write("Forecast: ");
|
||||
if (currentPressure > lastPressure) {
|
||||
writeln("Improving weather on the way!");
|
||||
} else if (currentPressure == lastPressure) {
|
||||
writeln("More of the same");
|
||||
} else if (currentPressure < lastPressure) {
|
||||
writeln("Watch out for cooler, rainy weather");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
module observer.delivery.heatindexdisplay;
|
||||
|
||||
import observer.delivery.displayelement;
|
||||
import observer.delivery.observer;
|
||||
import observer.delivery.weatherdata;
|
||||
import std.stdio : writeln;
|
||||
|
||||
class HeatIndexDisplay : Observer, DisplayElement
|
||||
{
|
||||
private:
|
||||
float heatIndex;
|
||||
|
||||
float computeHeatIndex(float t, float rh)
|
||||
{
|
||||
return ((16.923 + (0.185212 * t) + (5.37941 * rh) - (0.100254 * t * rh) + (0.00941695 * (t * t))
|
||||
+ (0.00728898 * (rh * rh)) + (0.000345372 * (t * t * rh)) - (0.000814971 * (t * rh * rh))
|
||||
+ (0.0000102102 * (t * t * rh * rh)) - (0.000038646 * (t * t * t)) + (0.0000291583 * (rh * rh * rh))
|
||||
+ (0.00000142721 * (t * t * t * rh)) + (0.000000197483 * (t * rh * rh * rh))
|
||||
- (0.0000000218429 * (t * t * t * rh * rh)) + 0.000000000843296 * (t * t * rh * rh * rh))
|
||||
- (0.0000000000481975 * (t * t * t * rh * rh * rh)));
|
||||
}
|
||||
public:
|
||||
this(WeatherData weatherData)
|
||||
{
|
||||
weatherData.registerObserver(this);
|
||||
}
|
||||
|
||||
override void update(float temperature, float humidity, float pressure)
|
||||
{
|
||||
this.heatIndex = computeHeatIndex(temperature, humidity);
|
||||
display();
|
||||
}
|
||||
|
||||
override void display()
|
||||
{
|
||||
writeln("Heat index is ", heatIndex);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
module observer.delivery.observer;
|
||||
|
||||
interface Observer
|
||||
{
|
||||
void update(float temperature, float humidity, float pressure);
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
module observer.delivery.statiscticdisplay;
|
||||
|
||||
import observer.delivery.displayelement;
|
||||
import observer.delivery.observer;
|
||||
import observer.delivery.weatherdata;
|
||||
import std.stdio : writeln;
|
||||
import std.format : format;
|
||||
|
||||
class StatisticsDisplay : Observer, DisplayElement
|
||||
{
|
||||
private:
|
||||
float maxTemp = 0.0f;
|
||||
float minTemp = 200;
|
||||
float tempSum= 0.0f;
|
||||
int numReadings;
|
||||
public:
|
||||
this(WeatherData weatherData)
|
||||
{
|
||||
weatherData.registerObserver(this);
|
||||
}
|
||||
|
||||
override void update(float temperature, float humidity, float pressure)
|
||||
{
|
||||
tempSum += temperature;
|
||||
numReadings++;
|
||||
|
||||
if (temperature > maxTemp)
|
||||
{
|
||||
maxTemp = temperature;
|
||||
}
|
||||
|
||||
if (temperature < minTemp)
|
||||
{
|
||||
minTemp = temperature;
|
||||
}
|
||||
|
||||
display();
|
||||
}
|
||||
|
||||
override void display()
|
||||
{
|
||||
writeln("Avg/Max/Min temperature = ", (tempSum / numReadings), '/', maxTemp, '/', minTemp);
|
||||
// writeln("Avg/Max/Min temperature = ".format(temperature), "F degrees and %3.1f%% humidity".format(humidity));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
module observer.delivery.subject;
|
||||
|
||||
import observer.delivery.observer;
|
||||
|
||||
interface Subject
|
||||
{
|
||||
void registerObserver(Observer o);
|
||||
void removeObserver(Observer o);
|
||||
void notifyObservers();
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
module observer.delivery.weatherdata;
|
||||
|
||||
import observer.delivery.subject;
|
||||
import observer.delivery.observer;
|
||||
import std.algorithm : remove, countUntil;
|
||||
|
||||
class WeatherData : Subject
|
||||
{
|
||||
private:
|
||||
Observer[] observers;
|
||||
float temperature, humidity, pressure;
|
||||
public:
|
||||
override void registerObserver(Observer o)
|
||||
{
|
||||
observers ~= o;
|
||||
}
|
||||
|
||||
override void removeObserver(Observer o)
|
||||
{
|
||||
// Вызовет ошибку в случае отсутствия элемента в массиве после его поиска
|
||||
// observers = observers.remove(observers.countUntil(o));
|
||||
observers = remove!(current => current == o)(observers);
|
||||
}
|
||||
|
||||
override void notifyObservers()
|
||||
{
|
||||
foreach (Observer o; observers)
|
||||
{
|
||||
o.update(temperature, humidity, pressure);
|
||||
}
|
||||
}
|
||||
|
||||
void measurementsChanged()
|
||||
{
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
void setMeasurements(float temperature, float humidity, float pressure)
|
||||
{
|
||||
this.temperature = temperature;
|
||||
this.humidity = humidity;
|
||||
this.pressure = pressure;
|
||||
measurementsChanged();
|
||||
}
|
||||
|
||||
@property float getTemperature()
|
||||
{
|
||||
return temperature;
|
||||
}
|
||||
|
||||
@property float getHumidity()
|
||||
{
|
||||
return humidity;
|
||||
}
|
||||
|
||||
@property float getPressure()
|
||||
{
|
||||
return pressure;
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
module observer.app;
|
||||
module observer.request.app;
|
||||
|
||||
import observer.weatherdata;
|
||||
import observer.currentconditionsdisplay;
|
||||
import observer.heatindexdisplay;
|
||||
import observer.forecastdisplay;
|
||||
import observer.statiscticdisplay;
|
||||
import observer.request.weatherdata;
|
||||
import observer.request.currentconditionsdisplay;
|
||||
import observer.request.heatindexdisplay;
|
||||
import observer.request.forecastdisplay;
|
||||
import observer.request.statiscticdisplay;
|
||||
|
||||
void main()
|
||||
{
|
|
@ -1,8 +1,8 @@
|
|||
module observer.currentconditionsdisplay;
|
||||
module observer.request.currentconditionsdisplay;
|
||||
|
||||
import observer.displayelement;
|
||||
import observer.observer;
|
||||
import observer.weatherdata;
|
||||
import observer.request.displayelement;
|
||||
import observer.request.observer;
|
||||
import observer.request.weatherdata;
|
||||
import std.stdio : writeln;
|
||||
import std.format : format;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
module observer.displayelement;
|
||||
module observer.request.displayelement;
|
||||
|
||||
interface DisplayElement
|
||||
{
|
|
@ -1,8 +1,8 @@
|
|||
module observer.forecastdisplay;
|
||||
module observer.request.forecastdisplay;
|
||||
|
||||
import observer.displayelement;
|
||||
import observer.observer;
|
||||
import observer.weatherdata;
|
||||
import observer.request.displayelement;
|
||||
import observer.request.observer;
|
||||
import observer.request.weatherdata;
|
||||
import std.stdio : write, writeln;
|
||||
import std.format : format;
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
module observer.heatindexdisplay;
|
||||
module observer.request.heatindexdisplay;
|
||||
|
||||
import observer.displayelement;
|
||||
import observer.observer;
|
||||
import observer.weatherdata;
|
||||
import observer.request.displayelement;
|
||||
import observer.request.observer;
|
||||
import observer.request.weatherdata;
|
||||
import std.stdio : writeln;
|
||||
|
||||
class HeatIndexDisplay : Observer, DisplayElement
|
|
@ -1,4 +1,4 @@
|
|||
module observer.observer;
|
||||
module observer.request.observer;
|
||||
|
||||
interface Observer
|
||||
{
|
|
@ -1,8 +1,8 @@
|
|||
module observer.statiscticdisplay;
|
||||
module observer.request.statiscticdisplay;
|
||||
|
||||
import observer.displayelement;
|
||||
import observer.observer;
|
||||
import observer.weatherdata;
|
||||
import observer.request.displayelement;
|
||||
import observer.request.observer;
|
||||
import observer.request.weatherdata;
|
||||
import std.stdio : writeln;
|
||||
import std.format : format;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
module observer.subject;
|
||||
module observer.request.subject;
|
||||
|
||||
import observer.observer;
|
||||
import observer.request.observer;
|
||||
|
||||
interface Subject
|
||||
{
|
|
@ -1,7 +1,7 @@
|
|||
module observer.weatherdata;
|
||||
module observer.request.weatherdata;
|
||||
|
||||
import observer.subject;
|
||||
import observer.observer;
|
||||
import observer.request.subject;
|
||||
import observer.request.observer;
|
||||
import std.algorithm : remove, countUntil;
|
||||
|
||||
class WeatherData : Subject
|
|
@ -2,8 +2,7 @@
|
|||
|
||||
Инкапсуляция алгоритма в объект — это назначение паттерна **стратегия**.
|
||||
|
||||
Поведенческий паттерн проектирования, который определяет семейство схожих алгоритмов и
|
||||
помещает каждый из них в собственный класс, после чего алгоритмы можно взаимозаменять прямо во время исполнения программы.
|
||||
Поведенческий паттерн проектирования, который определяет семейство схожих алгоритмов и помещает каждый из них в собственный класс, после чего алгоритмы можно взаимозаменять прямо во время исполнения программы.
|
||||
|
||||
## Код
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
module strategy.duck;
|
||||
|
||||
import strategy.flybehavior;
|
||||
import strategy.quackbehavior;
|
||||
import std.stdio : writeln;
|
||||
|
|
Reference in New Issue