> For the complete documentation index, see [llms.txt](https://programmingfundamental.gitbook.io/programmingwithjava/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://programmingfundamental.gitbook.io/programmingwithjava/obektno-orientirano-programirane-2-chast/laboratorno-uprazhnenie-6/decorator.md).

# Decorator

Декораторът е представител на структурните шаблони. Неговото предназначение е динамично да добавя характеристики и функционалности към вече съществуващи обекти, без това да променя тяхната структура. Декораторът се явява като обгръщащ (wrapper) клас за вече съществуващия и имплементира същия интерфейс.

Като илюстрация на шаблона декоратор, нека разгледме следния пример:

Декларираме интерфейс Book:

```
public interface Book {
    String decorateBook();
}
```

Необходим е също така клас BookImpl:

```
public class BookImpl implements Book{
    @Override
    public String decorateBook() {
        return "Book has: ";
    }
}
```

Следващата стъпка е създаването на абстрактен клас BookDecorator, в който като частно поле декларираме обект от интерфейса:

```
public abstract class BookDecorator implements Book {
    private Book book;
    public BookDecorator(Book book) {
        this.book = book;
    }
    @Override
    public String decorateBook() {
        return book.decorateBook();
    }
}
```

Този клас ще бъде базовия декоратор, като всички останали ще го наследяват.

```
public class HardCoverDecorator extends BookDecorator {
    public HardCoverDecorator(Book book) {
        super(book);
    }
    @Override
    public String decorateBook() {
        return super.decorateBook() + addHardCover();
    }
    private String addHardCover() {
        return "\n hard cover";
    }
}
```

```
public class CoverIllustrationsDecorator extends BookDecorator {
    public CoverIllustrationsDecorator(Book book){
        super(book);
    }
    @Override
    public String decorateBook() {
        return super.decorateBook() + addCoverIllustrations();
    }
    private String addCoverIllustrations() {
        return "\ncover illustrations";
    }
}
```

```
public class BookIllustrationsDecorator extends BookDecorator {
    public BookIllustrationsDecorator(Book book) {
        super(book);
    }
    @Override
    public String decorateBook() {
        return super.decorateBook() + addBookIllustrations();
    }
    private String addBookIllustrations() {
        return "\n book illustrations";
    }
}
```

```
public class VolumeDecorator extends BookDecorator {
    public VolumeDecorator(Book book) {
        super(book);
    }
    @Override
    public String decorateBook() {
        return super.decorateBook() + addVolume();
    }
    private String addVolume() {
        return "\n more than one volume";
    }
}
```

Създаването на обекти и използването на различните декоратори е илюстрирано със следващия програмен фрагмент:

```
public class Main {
    public static void main(String[] args) {
        Book book = new BookImpl();
        Book firstBook = new HardCoverDecorator(book);
        System.out.println("First " + firstBook.decorateBook() + "\n");
        Book secondBook = new HardCoverDecorator(new CoverIllustrationsDecorator(book));
        System.out.println("Second " + secondBook.decorateBook() + "\n");
        Book thirdBook = new VolumeDecorator(new HardCoverDecorator(new BookIllustrationsDecorator(book)));
        System.out.println("Third " + thirdBook.decorateBook() + "\n");
        Book fourthBook = new VolumeDecorator(new VolumeDecorator(book));
        System.out.println("Fourth " + fourthBook.decorateBook());
    }
}
```

Вижда се, че създаването на книги може да става с различни комбинации от декларираните декоратори, както и повече от едно извикване на един и същи декоратор.

Резултатът е следния:

Кога се използва декоратор:

* Когато желаем динамично да добавяме отговорности към обекти без това да оказва влияние върху други такива;
* Когато е необходимо да добавим функционалности към обект, които може да променим в бъдеще;
* Когато добавянето на наследници/подкласове вече не е практично (станат прекалено много).

Предимства от използването на шаблон Декоратор:

* Предоставя по-голяма гъвкавост в сравнение със статичното наследяване;\\
* Разширява и променя поведението на обекта без използване на подкласове/наследници;
* Дава възможност за комбиниране на различни функционалности чрез обгръщане на дадения клас с различни декоратори (последните три обекта в горния пример).

Като недостатък на декоратора може да се посочи факта, че е трудно неговото имплементиране по начин, по който неговото поведение да не зависи от поредността на извикванията.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://programmingfundamental.gitbook.io/programmingwithjava/obektno-orientirano-programirane-2-chast/laboratorno-uprazhnenie-6/decorator.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
