Паттерн проектування декоратор дозволяє нам динамічно додавати функціональність об'єкту без впливу на поведінку об'єктів того самого класу. Звучить трохи заплутано, але коли побачите код, все стане зрозуміліше. Особливості — Декоратор дозволяє додавати функціональність існуючому об'єкту без зміни його структури, тобто вихідний клас не змінюється. — Паттерн проектування декоратор — це структурний патерн, який забезпечує обгортку для існуючого класу. методів вихідного класу незайманими - Паттерн проектування декоратор найчастіше використовується для дотримання принципу єдиної відповідальності (single responsibility з SOLID), оскільки ми не навантажуємо вихідний клас додатковими обов'язками, а поділяємо їх на класи-декоратори - Декоратор структурно майже аналогічний патерну "ланцюжок відповідальності" ( chain of responsibility) Необхідно враховувати такі ключові моменти - Декоратор корисний для можливості модифікувати поведінку об'єкта під час рантайму. Такий код легко підтримувати та розширювати. - Недоліком цього патерну є те, що використовується велика кількість однотипних об'єктів-декораторів - Паттерн декоратор часто використовується в класах Java IO (FileReader, BufferedReader і т. д.) Що зробимо реалізує цей інтерфейс - Створимо конкретний декоратор, що успадковується від абстрактного декоратора - Використовуємо конкретний декоратор для "декорування" конкретних реалізацій інтерфейсу . Ми створимо інтерфейс Shape та конкретні класи, що реалізують цей інтерфейс. Потім ми створимо абстрактний клас-декоратор ShapeDecorator, що реалізує інтерфейс Shape і має об'єкт Shape як поле класу. - Shape - ім'я інтерфейсу - Класи Rectangle, Triangle і клас Circle будуть конкретними класами, що реалізують інтерфейс Shape - ShapeDecorator - це абстрактний клас-декоратор, що реалізує той же інтерфейс Shape - RedShapeDecorator - конкретний клас, що реалізує ShapeDecorator - Demo - демонстр ми будемо використовувати RedShapeDecorator для декорування об'єктів Shape Крок 1 : створюємо інтерфейс Shape
public interface Shape {
void draw();
}
Крок 2 : створимо кілька реалізацій цього інтерфейсу. У прикладі нижче буде лише коло, а за фактом створимо ще кілька: прямокутник і трикутник.
public class Circle implements Shape{
@Override
public void draw() {
System.out.println("Я круг!");
}
}
Крок 3 : створимо абстрактний декоратор, що реалізує інтерфейс Shape
public abstract class ShapeDecorator implements Shape {
protected Shape decoratedShape;
//Конструктор, принимающий об'єкт Shape
public ShapeDecorator(Shape decoratedShape) {
this.decoratedShape = decoratedShape;
}
public void draw() {
decoratedShape.draw();
}
}
Крок 4 : створимо конкретний клас-декоратор, що наслідує абстрактний клас
public class RedShapeDecorator extends ShapeDecorator{
public RedShapeDecorator(Shape decoratedShape) {
super(decoratedShape);
}
@Override
public void draw() {
decoratedShape.draw();
setRedBorder(decoratedShape);
}
private void setRedBorder(Shape decoratedShape) {
System.out.println("Сообщение от RedShapeDecorator. Цвет границы: красный");
}
}
Крок 5 : використовуємо RedShapeDecorator щоб розфарбувати наші об'єкти
public class Demo {
public static void main(String[] args)
{
Shape circle = new Circle();
Shape redCircle= new RedShapeDecorator(new Circle());
Shape redRectangle= new RedShapeDecorator(new Rectangle());
Shape redTriangle = new RedShapeDecorator(new Triangle());
System.out.println("\nОбычный круг:");
circle.draw();
System.out.println("\nКруг с красной границей:");
redCircle.draw();
System.out.println("\nПрямоугольник с красной границей:");
redRectangle.draw();
System.out.println("\nТреугольник с красной границей:");
redTriangle.draw();
}
}
Крок 6 : дивимося в консоль і радіємо
Обычный круг:
Я круг!
Круг с красной границей:
Я круг!
Сообщение от RedShapeDecorator. Цвет границы: красный
Прямоугольник с красной границей:
Я прямоугольник!
Сообщение от RedShapeDecorator. Цвет границы: красный
Треугольник с красной границей:
Я треугольник!
Сообщение от RedShapeDecorator. Цвет границы: красный
Розібравши на прикладі патерн проектування декоратор, можна дійти невтішного висновку, що його використання виправдано у таких случаях: — Коли ми хочемо додати, поліпшити чи, можливо, видалити поведінка чи стан об'єкта — Коли ми хочемо змінити функціональність одного конкретного об'єкта класу, інші ж залишити без змін Дякуємо! Репозиторій з файлуми проекту За основу взято статтю із сайту geeksforgeeks.org Мій блог Java Dev
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ