Skip to content
Home » Blog » Decorator design pattern

Decorator design pattern

Another design pattern that I will describe will be the title decorator. This pattern can be easily imagined as an implementation of the work of an interior decorator who, getting an unfinished apartment, decorates it with various gadgets. As a result, we get the same apartment, but it is already modified. What does it look like in programming? I invite you to read.

Let's present the problem

The decorator pattern assumes the existence of two kinds of classes, which we will colloquially call the decorated and decorating class. In the example of an interior decorator, the class will decorate the apartment, and the class will decorate the ornament, or the decorative element that decorates the apartment. Every action performed by the decorator in the apartment causes that the apartment is still an apartment, but gains new functionalities.

At this point, one could directly think that inheritance is ideally suited to this mechanism. The problem is that each decorator has a palette of beaten paths and elements to use in his work. After all, why reinvent the wheel for each project? Creating the final project each time would require the decorator to write many classes, each of which would add one effect to the apartment, which, with many projects carried out by him, would multiply a lot of classes that would be difficult to reuse. Let's see an example below:

flat 1

class Mieszkanie {
    int iloscScian = 4;
}

class MieszkanieJasne
extends Mieszkanie{
    String kolor = "biały";
}

class MieszkanieBialeDuze
extends MieszkanieBiale{
    double powierzchniaM2 = 120;
}

class MieszkanieBialeDuzeZBalkonem
extends MieszkanieBialeDuze{
    boolean balkon = true;
}

flat 2

class Mieszkanie {
    int iloscScian = 4;
}

class MieszkanieCiemne 
extends Mieszkanie{
    String kolor = "czarny";
}

class MieszkanieCiemneMale
extends MieszkanieCiemne{
    double powierzchniaM2 = 42;
}

class MieszkanieCiemneMaleZTarasem
extends MieszkanieCiemneMale{
    boolean taras = true;
}

Note that if we only wanted to create a small bright apartment with a terrace, we can only use the MieszkanieJasne class, while the remaining 2 should be added. This is not a convenient solution. Additionally, there is a problem when we want to compare two objects with each other. Note that both of them are of different types, so they cannot be compared to each other.

Let's solve the problem

An ideal solution for an interior decorator would be if he could compose each apartment from ready-made components, and then, for his own understanding, assess the attractiveness of the solution based on a parameter. This is where the decorator pattern triumphantly comes in.

At the very beginning, let's look at the final piece of code on which an interior decorator works to create new compositions.

Mieszkanie piekneMieszkanie = new MieszkanieNowe(); //tworzymy nasze piękne mieszkanie
piekneMieszkanie = new Jasne(piekneMieszkanie); //dekorujemy mieszkanie jasnymi ścianami
piekneMieszkanie = new ZTarasem(piekneMieszkanie); //dodajemy aranżację tarasu

Note that we are constantly working on our originally created object and wrapping it with new new objects. We do not change the type of object because we are still using the Apartment class. Both the object decorated with a beautiful Apartment and the decorating objects are of the same type, which may seem not very intuitive, but they offer great possibilities. The saved solution can be represented graphically as follows:

For type compatibility, all classes extend the base abstract class Apartment:

package com.company;

public abstract class Mieszkanie {
    String opis; //zawiera opis dodawanej funkcjonalnosci

    public String getOpis() {
        return opis;
    }

    public abstract int indeksWartosci(); //zwraca wartosc wspolczynnika atrakcyjnosci mieszkania

}

On this basis, we create our decorated class New Apartment (later you can create similarly other classes, such as Single-family House, Seregowiec, etc.):

package com.company;

public class MieszkanieNowe extends Mieszkanie { //rozszerzamy klase Mieszkanie

    public MieszkanieNowe() {
        opis = "Mieszkanie z rynku pierwotnego";
    }

    @Override
    public int indeksWartosci() {
        return 50;
    }
}

In this way, we created a decorated class which is the starting point of the entire composition. Now we'll move on to creating decorators, and we'll start with the fact that, as previously mentioned, the decorating class must be of the same type as the decorating class. So let's create a class:

package com.company;

public abstract class Ozdoba extends Mieszkanie{
    public abstract String getOpis();
}

We will use this class to create appropriate decorating classes, such as:

package com.company;

public class Jasne extends Ozdoba {
    Mieszkanie mieszkanie;

    public Jasne(Mieszkanie mieszkanie) {
        this.mieszkanie = mieszkanie;
    }

    @Override
    public int indeksWartosci() {
        return mieszkanie.indeksWartosci() + 4;
    }

    @Override
    public String getOpis() {
        return mieszkanie.getOpis() + " + Sciany jasne";
    }
}
package com.company;

public class ZTarasem extends Ozdoba {
    Mieszkanie mieszkanie;

    public ZTarasem(Mieszkanie mieszkanie) {
        this.mieszkanie = mieszkanie;
    }

    @Override
    public int indeksWartosci() {
        return mieszkanie.indeksWartosci() + 10;
    }

    @Override
    public String getOpis() {
        return mieszkanie.getOpis() + " + Taras";
    }
}

Note that in the constructor of both classes I pass the existing apartment object already decorated in some way and in the methods indexWartosci () and getOpis () I add new data to the previous object.

We just created a simple application implementing the decorator pattern. Finally, let's see how our application will work after putting together all the classes in main:

package com.company;

public class Main {

    public static void main(String[] args) {
        Mieszkanie piekneMieszkanie = new MieszkanieNowe(); //tworzymy nasze piękne mieszkanie
        piekneMieszkanie = new Jasne(piekneMieszkanie); //dekorujemy mieszkanie jasnymi ścianami
        piekneMieszkanie = new ZTarasem(piekneMieszkanie); //dodajemy aranżację tarasu

        System.out.println("Indeks wartości:  " + piekneMieszkanie.indeksWartosci() + ", zawiera:  " + piekneMieszkanie.getOpis());
    }
}

The program output looks like this:

Indeks wartości:  64, zawiera:  Mieszkanie z rynku pierwotnego + Sciany jasne + Taras

Process finished with exit code 0

Note that now it is very easy to add new classes, both decorated and decorated, because each time we can safely use previously written classes without worrying about their mutual compatibility.

Finally, I will present the definition of the decorator pattern, which should be more understandable to you after reading this article:

Decorator design pattern allows you to dynamically assign new behaviors to a given object. Decorators provide flexibility similar to inheritance, but offer significantly expanded functionality in return.

In the above definition, it is also worth paying attention to the word dynamic , because nothing prevents our interior decorator from implementing a solution based on artificial intelligence in the future. It would collect information about the owner of the apartment and on this basis, while the program is running, it would simulate how the apartment could be arranged for the client.

I hope that my article convinced you and gave you understanding about the decorator pattern, and if you have any comments, feel free to comment or contact us via the form.

W celu świadczenia usług na najwyższym poziomie stosuję pliki cookies, które będą zamieszczane w Państwa urządzeniu (komputerze, laptopie, smartfonie). W każdym momencie mogą Państwo dokonać zmiany ustawień Państwa przeglądarki internetowej i wyłączyć opcję zapisu plików cookies. Ze szczegółowymi informacjami dotyczącymi cookies na tej stronie można się zapoznać tutaj: View more
Cookies settings
Akceptuj
Blokuj
Privacy policy
Privacy & Cookies policy
Cookie name Active

The privacy policy describes the rules for the processing of information about you, including personal data and cookies, i.e. cookies.


1. General information

  1. This policy applies to the website operating at the url address: www.wojciechsiwek.pl
  2. The website operator and the personal data administrator is: Wojciech Siwek
  3. The operator's e-mail contact address: wojciech.siwek.programista@gmail.com
  4. The operator is the Administrator of your personal data in relation to the data provided voluntarily on the Website.
  5. The website uses personal data for the following purposes:
    • Running a comment system
    • Handling inquiries via the form
  6. The website obtains information about users and their behavior in the following way:
    1. Through data entered voluntarily in forms, which are entered into the Operator's systems.
    2. By saving cookie files in end devices (so-called "cookies").

2. Selected data protection methods used by the Operator

  1. The places of logging in and entering personal data are protected in the transmission layer (SSL certificate). As a result, personal data and login data entered on the website are encrypted on the user's computer and can only be read on the target server.
  2. User passwords are stored in a hashed form. The hash function works in one direction - it is not possible to reverse its operation, which is now a modern standard in the field of storing user passwords.
  3. The operator periodically changes his administrative passwords.
  4. In order to protect data, the Operator regularly makes backup copies.
  5. In order to protect data, an essential element of data protection is regular updating of all software used by the Operator to process personal data, which in particular means regular updates of programming components. The Operator regularly makes backup copies.

3. Hosting

  1. The website is hosted (technically maintained) on the operator's server: NETMARK.

4. Your rights and additional information on how to use the data

  1. In some situations, the Administrator has the right to transfer your personal data to other recipients if it is necessary to perform the contract concluded with you or to fulfill the obligations incumbent on the Administrator. This applies to such groups of recipients:
    • postal operators
    • comment system operators
    • authorized employees and associates who use the data to achieve the purpose of the website
  2. Your personal data processed by the Administrator for no longer than it is necessary to perform the related activities specified in separate regulations (e.g. on accounting). With regard to marketing data, the data will not be processed for more than 3 years.
  3. You have the right to request from the Administrator:
    • access to your personal data,
    • rectifying them,
    • deletion,
    • processing restrictions,
    • and data portability.
  4. You have the right to object to the processing indicated in point 3.3 c) to the processing of personal data in order to perform the legitimate interests pursued by the Administrator, including profiling, while the right to object may not be exercised if there are valid legally justified grounds for processing of your interests, rights and freedoms, in particular establishing, investigating or defending claims.
  5. The Administrator's actions may be appealed against to the President of the Personal Data Protection Office, ul. Stawki 2, 00-193 Warsaw.
  6. Providing personal data is voluntary, but necessary to operate the Website.
  7. In relation to you, actions may be taken consisting in automated decision making, including profiling to provide services under the concluded contract and for the purpose of conducting direct marketing by the Administrator.
  8. Personal data is not transferred from third countries within the meaning of the provisions on the protection of personal data. This means that we do not send them outside the European Union.

5. Information in the forms

  1. Serwis zbiera informacje podane dobrowolnie przez użytkownika, w tym dane osobowe, o ile zostaną one podane.
  2. The website may save information about connection parameters (time stamp, IP address).
  3. The website, in some cases, may save information facilitating the linking of data in the form with the e-mail address of the user filling in the form. In this case, the user's e-mail address appears inside the url of the page containing the form.
  4. The data provided in the form is processed for the purpose resulting from the function of a specific form, eg to process the service request or commercial contact, service registration, etc. Each time the context and description of the form clearly informs what it is used for.

6. Administrator logs

  1. Information on the behavior of users on the website may be subject to logging. These data are used to administer the website.

7. Relevant marketing techniques

  1. The operator uses statistical analysis of website traffic through Google Analytics (Google Inc. based in the USA). The operator does not provide personal data to the operator of this service, but only anonymised information. The service is based on the use of cookies on the user's end device. In terms of information about user preferences collected by the Google advertising network, the user can view and edit information derived from cookies using the tool: https://www.google.com/ads/preferences/

8. Information about cookies

  1. The website uses cookies.
  2. Cookie files (so-called "cookies") are IT data, in particular text files, which are stored on the Website User's end device and are intended for using the Website's pages. Cookies usually contain the name of the website they come from, the storage time on the end device and a unique number.
  3. The entity that places cookies on the Website User's end device and obtains access to them is the Website operator.
  4. Cookies are used for the following purposes:
    1. maintaining the Website user's session (after logging in), thanks to which the user does not have to re-enter the login and password on each subpage of the Website;
    2. achieving the goals set out above in the section "Important marketing techniques";
  5. The Website uses two basic types of cookies: session cookies and persistent cookies. Session cookies are temporary files that are stored on the User's end device until logging out, leaving the website or turning off the software (web browser). Persistent cookies are stored on the User's end device for the time specified in the cookie file parameters or until they are deleted by the User.
  6. Software for browsing websites (web browser) usually allows cookies to be stored on the User's end device by default. Website Users can change the settings in this regard. The web browser allows you to delete cookies. It is also possible to automatically block cookies.Detailed information on this subject can be found in the help or documentation of the web browser.
  7. Restrictions on the use of cookies may affect some of the functionalities available on the Website pages.
  8. Cookies placed on the Website User's end device may also be used by entities cooperating with the Website operator, in particular the following companies: Google (Google Inc. based in the USA), Facebook (Facebook Inc. based in the USA), Twitter (Twitter Inc. based in the USA).

9. Managing cookies - how to express and withdraw consent in practice?

  1. If the user does not want to receive cookies, he may change the browser settings. We reserve that disabling cookies necessary for authentication processes, security, maintaining user preferences may make it difficult, and in extreme cases may prevent the use of websites.
  2. In order to manage cookie settings, select the web browser you use from the list below and follow the instructions:
Save settings
Cookies settings