[Java] Decorator pattern

2 minute read

What is Derocator pattern

Decorate the objects.

Component role

The core role when adding functions.

``’’ java package decorator;

public abstract class Display { public abstract int getColumns(); public abstract int getRows(); public abstract String getRowText(int row); public final void show() { for (int i = 0; i <getRows(); i++) { System.out.println(getRowText(i)); } } }


### The role of ConcreteComponent
Role that implements the interface of Component role.

``'' java
package decorator;

/**
 * Class that displays a one-line string
 */
public class StringDisplay extends Display{
private String string;

public StringDisplay(String string) {
this.string = string;
}

@Override
public int getColumns() {
return string.getBytes().length;
}

@Override
public int getRows() {
return 1;
}

@Override
public String getRowText(int row) {
return row == 0 ?string :null;
}
}

The role of the decorator

It has the same interface as Component. It also has a Component role that the Decorator role decorates. This character knows what to decorate.

``’’ java package decorator;

/**

  • Class that represents a decorative frame */ public abstract class Border extends Display { // refers to the “contents” that this decorative frame is wrapped in protected Display display; protected Border(Display display) { this.display = display; } } ````

Concrete Decorator role

Concrete role of Decorator.

``’’ java package decorator;

/**

  • A class to decorate the left and right of the string with fixed characters * */ public class SideBorder extends Border { private char borderChar;

protected SideBorder(Display display, char ch) { super(display); this.borderChar = ch; }

@Override public int getColumns() { // The number of characters is the number of decorative characters added to both sides return 1 + display.getColumns() + 1; }

@Override public int getRows() { return display.getRows(); }

@Override public String getRowText(int row) { return borderChar + display.getRowText(row) + borderChar; } }


``'' java
package decorator;

/**
 * Class with decorations on the top, bottom, left and right
 *
 */
public class FullBorder extends Border{

protected FullBorder(Display display) {
super(display);
}

@Override
public int getColumns() {
// The number of characters is the number of decorative characters added to both sides
return 1 + display.getColumns() + 1;
}

@Override
public int getRows() {
// The number of characters is the one with decorative characters added to the top and bottom
return 1 + display.getRows() + 1;
}

@Override
public String getRowText(int row) {
if (row == 0) {
// Above the frame
return "+" + makeLine('-', display.getColumns()) +'+';
} else if (row == display.getRows() + 1) {
// bottom of frame
return "+" + makeLine('-', display.getColumns()) +'+';
 } else {
 return "|" + display.getRowText(row-1) + "|";
 }
}

/**
* Create specified characters in succession
*
*/
private String makeLine(char ch, int count) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i <count; i++) {
buf.append(ch);
}
return buf.toString();
}
}

Caller

``’’ java package decorator;

public class Main { public static void main(String[] args) { Display d1 = new StringDisplay(“Hello world”); Display d2 = new SideBorder(d1,’#’); Display d3 = new FullBorder(d2); d1.show(); d2.show(); d3.show(); } } ````

Execution result

![Screenshot 2020-09-09 14.19.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197834/81e11759-99b6-4cca-8b38-(fc00a9a7e6a4.png)

The more you wrap, the more features you will add. At that time, the function can be added without changing the wrapped side.

https://github.com/aki0207/decorator

I referred to this. Introduction to Design Patterns Learned from the Enhanced and Revised Java Language

Tags:

Updated: