GofPatterns Gofpatterns





Structural Patterns  «Prev 

Decorator Pattern in Java

Description:

The Decorator is known as a structural pattern, because it is used to form large object structures across many disparate objects. The definition of Decorator provided in the original Gang of Four book on Design Patterns states:
Allows for the dynamic wrapping of objects in order to modify their existing responsibilities and behaviours

You might consider subclassing to be the best way to approach this challenge. However, there will be cases where subclassing is not possible.
This leads us to the Open/Closed Principle: classes should be open for extension, but closed for modification. This is a good principle to keep in mind, as it keeps your class stable, but leaves it open for extension if someone wants to add behaviour.
Here is the Decorator Pattern in Java

The following is an email interface, which contains a getContents method:
package com.java.structural.decorator;

public interface IEmail{
  public String getContents();
}

I then provide a concrete implementation for use:
package com.java.structural.decorator;

//concrete component
public class Email implements IEmail{
  private String content;
  public Email(String content){
    this.content = content;
  }
  @Override
  public String getContents() {
    return content;
  }
}


Create a decorator which will wrap the base email with additional functionality and model this as an abstract class, and maintain a reference to the base email.

package com.java.structural.decorator;

public abstract class EmailDecorator implements IEmail {
  IEmail originalEmail;
}

Assumption: Emails that leave the company's internal server need to have a disclaimer added to the end and we will add in a decorator to handle this scenario.

package com.java.structural.decorator;
//concrete decorator
public class ExternalEmailDecorator extends EmailDecorator{
  private String content; 
  public ExternalEmailDecorator(IEmail basicEmail){
    originalEmail = basicEmail;
  }
  @Override
  public String getContents() {
    content = addDisclaimer(originalEmail.getContents());
    return content;
  }
  private String addDisclaimer(String message){
	  //append company disclaimer to message
    return  message + "\n Company Disclaimer";
  } 
}

Create a secure, encrypted message by using another decorator:
package com.java.structural.decorator;

//concrete decorator
public class SecureEmailDecorator extends EmailDecorator{
  private String content; 
  public SecureEmailDecorator(IEmail basicEmail){
    originalEmail = basicEmail;
  }
  @Override
  public String getContents(){
  //secure original 
    content = encrypt(originalEmail.getContents());
    return content;
  }
  private String encrypt(String message) {
    String encryptedMessage=message;
    return  encryptedMessage;
  }
}

If our email sending client detects this message is going outside the company, we can invoke the ExternalEmailDecorator before sending:

package com.java.structural.decorator;

public class EmailSender {
  public void sendEmail(IEmail email) {
  /*read the email to-address, to see if it
  is going outside of the company*/
  ExternalEmailDecorator external = new ExternalEmailDecorator(email);
  external.getContents();
  }
}