xxxxxxxxxx
// Java Decorator pattern
public interface WebPage { // Component interface
public void display();
}
public class BasicWebPage implements WebPage{ // Base Concrete Component
public void display() {
System.out.println("renders HTML to stylesheet, run scripts");
}
}
public abstract class WebPageDecorator implements WebPage{
// one instance of WebPage, allow stacking
protected WebPage webpage;
// constructor allow different subtypes of WebPage to
// be linked together in a stack
public WebPageDecorator (WebPage webpage) {
this.webpage = webpage;
}
public void display() {this.webpage.display();}
}
public class AuthorizedWebPage extends WebPageDecorator{ // Concrete Decorator
// constructor uses abstract superclass's constructor
// allows decorators to be stacked together
public AuthorizedWebPage(WebPage decoratedPage) {
super(decoratedPage);
}
// each decorator has its own responsibility
public void authorizedUser() {System.out.println("Authorizing user");}
public void display() {
// to resursively call the display() behavior
// concrete decorators invoke superclass's display() method
// call to super.display() will cause the next WebPage in the
// stack to execute its version until get to BasicWebPage,
// where recursion will end b/c BasicWebPage is a concrete component
// which does not aggregate other types of WebPage
super.display();
this.authorizedUser();
}
}
//Concrete Decorator
public class AuthenticatedWebPage extends WebPageDecorator{
public AuthenticatedWebPage(WebPage decoratedPage) {
super(decoratedPage);
}
public void authenticateUser() {
System.out.println("Authenticating user");
}
public void display() {
super.display();
this.authenticateUser();
}
}
public class Program {
public static void main(String[] args) {
// stacking objects into an aggregate
// the order you build the stack matters ()
WebPage myPage = new BasicWebPage();
myPage = new AuthorizedWebPage(myPage);
myPage = new AuthenticatedWebPage(myPage);
// recursively invoke aggregation stack to combine behavior
myPage.display();
}
}
// renders HTML to stylesheet, run scripts
// Authorizing user
// Authenticating user
xxxxxxxxxx
// The 'component' abstract class
public abstract class Beverage
{
String description = "Unknown Beverage"
public String getDescription()
{
return description;
}
public abstract double cost();
// Other useful methods here
}
// The 'ConcreteComponent' classes
public class HouseBlend extends Beverage
{
public HouseBlend()
{
description = "House Blend Coffee";
}
public cost double()
{
return 0.80;
}
}
class DarkRoast extends Beverage
{
public DarkRoast()
{
description = "Dark Roast Coffee";
}
public double cost()
{
return 0.90;
}
}
class Espresso extends Beverage
{
public Espresso()
{
description = "Espresso";
}
public double cost()
{
return 1.99;
}
}
class Decaf extends Beverage
{
public Decaf()
{
description = "Decaf Coffee";
}
public double cost()
{
return 1.05;
}
}
// The 'Decorator' abstract class
abstract class CondimentDecorator extends Beverage
{
public abstract String getDescription();
}
// The 'ConcreteDecorator' classes
class Milk extends CondimentDecorator
{
Beverage beverage;
public Milk(Beverage beverage)
{
this.beverage = beverage;
}
public String getDescription()
{
return beverage.getDescription() + ", Milk";
}
public double cost()
{
return beverage.cost() + 10; // Assuming milk adds 0.10 to the cost
}
}
xxxxxxxxxx
// Interface for the component that will be decorated
interface Component {
void operation();
}
// Concrete implementation of the component
class ConcreteComponent implements Component {
@Override
public void operation() {
System.out.println("ConcreteComponent operation");
}
}
// Abstract decorator class
abstract class Decorator implements Component {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void operation() {
component.operation();
}
}
// Concrete decorator class adding extra functionality
class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
@Override
public void operation() {
super.operation();
addExtraFunctionality();
}
private void addExtraFunctionality() {
System.out.println("Added extra functionality");
}
}
public class Main {
public static void main(String[] args) {
// Creating a concrete component
Component component = new ConcreteComponent();
// Decorating the component with extra functionality
Component decoratedComponent = new ConcreteDecorator(component);
// Calling the operation on the decorated component
decoratedComponent.operation();
}
}