We associate the decorator with embellishing a given item. In programming, it de facto performs the same function, i.e. it beautifies objects and also makes them more detailed, makes the description more precise, which in turn allows for better reflection in our program. This can be done dynamically by assigning extensions to a given class. To understand this problem, let’s consider the Pizza Problem
First, let’s look at the abstract class of Pizza
public abstract class Pizza {
String nazwa="Unknown name";
public String getName() {
return name;
}
public abstract double cost();
}
As we can see, it only has a variable name. It’s high time to get to know the classes that inherit from her. So let’s go
public class Magrarita extends Pizza{
public Magrarita(){
nazwa="Pizza Margarita";
}
@Override
public double cost() {
return 40.99;
}
}
public class Pepperoni extends Pizza{
public Pepperoni(){
nazwa="Pizza Pepperoni";
}
@Override
public double cost() {
return 45.99;
}
}
Both classes override the cost method which returns the price of a given pizza and its name. Now let's take a different side to the problem and look at the abstract class Components
public abstract class Components extends Pizza{
public abstract String getName() ;
}
This class is intended to represent the individual ingredients of the pizza. The code for the ingredients is presented below.
public class MozzarellaCheese extends Components{
Pizza pizza;
public MozzarellaCheese(Pizza pizza){
this.pizza=pizza;
}
@Override
public double cost() {
return pizza.cost()+ 1.22;
}
@Override
public String getName() {
return pizza.getName()+ ", Mozarella Cheese";
}
}
public class GarlicSauce extends Components{
Pizza pizza;
public GarlicSauce(Pizza pizza){
this.pizza=pizza;
}
@Override
public double cost() {
return pizza.cost()+ 1.42;
}
@Override
public String getName() {
return pizza.getName()+ ", Garlic Sauce";
}
}
As we can observe, both classes inherit from the abstract class. Time to simulate the operation of the program
public class Test {
public static void main(String[] args){
Pizza pizza= new Pepperoni();
pizza= new MozarellaCheese(pizza);
pizza= new GarlicSauce(pizza);
System.out.println(pizza.getName()+ " "+ pizza.cost());
}
}
The result is as follows
Pizza Pepperoni, Ser Mozarella, Sos Czosnkowy 48.63
As we can observe, this example proves that it is possible to assign new classes to the pizza object that add the cost of individual ingredients to the pizza, which allows considering each class separately. It allows you to easily add new classes, such as tomato sauce or Parmesan, thanks to which we do not violate the principles of encapsulation.