Decorator Pattern Demo
package DecoratorPatternDemo;
public interface Beverage {
String getDescription();
double getCost();
}
package DecoratorPatternDemo;
public interface CondimentDecorator extends Beverage {
}
package DecoratorPatternDemo;
public class Coffee implements Beverage {
@Override
public String getDescription() {
return "Coffee";
}
@Override
public double getCost() {
return 1.99;
}
}
Of course, let's break it down.
The Decorator pattern allows us to add new functionality to an existing object without altering its structure. This is done by wrapping the original object and providing additional functionality through the wrapper.
Our example models a coffee shop where you can order a basic coffee and then add different condiments to it. Each condiment added increases the price of the coffee.
Interfaces: We start with two interfaces:
Beverage
: This is the basic interface that defines the required methods that all beverages must have, i.e.,getDescription
andgetCost
.CondimentDecorator
: This extends theBeverage
interface. Any class that implementsCondimentDecorator
is also aBeverage
, but with added functionality (in this case, the added functionality is an additional ingredient and cost).
Classes:
Coffee
: This is a basic type ofBeverage
. It has a description and cost.Milk
: This class represents a condiment and it is aCondimentDecorator
. It's constructed with aBeverage
(which can be a basic coffee or a coffee with other condiments). When you call itsgetDescription
method, it appends ", Milk" to the description of the beverage it was constructed with. When you call itsgetCost
method, it adds $0.30 to the cost of the beverage it was constructed with.
The main method in the CoffeeShop
class demonstrates how to use these classes and interfaces together. We create a Coffee
object and then decorate it with a Milk
object, and then print the description and cost.