Decorate the object.
The core role when adding functions.
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));
}
}
}
A role that implements the interface of the Component role.
package decorator;
/**
*A class that displays a single line of text
*/
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;
}
}
Has the same interface as the Component role. It also has a Component role that the Decorator role can decorate. This role knows what he wants to decorate.
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;
}
}
The role of a specific decorator.
package decorator;
/**
*A class that decorates the left and right sides of a character 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 on 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;
}
}
package decorator;
/**
*Class to decorate up, down, 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 on both sides
return 1 + display.getColumns() + 1;
}
@Override
public int getRows() {
//The number of characters is the top and bottom with decorative characters added
return 1 + display.getRows() + 1;
}
@Override
public String getRowText(int row) {
if (row == 0) {
//Upper side of the frame
return "+" + makeLine('-', display.getColumns()) + '+';
} else if (row == display.getRows() + 1) {
//The bottom of the 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();
}
}
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();
}
}
The more you wrap it, the more functions will be added. At that time, the function can be added without changing the wrapped side.
https://github.com/aki0207/decorator
I used this as a reference. Augmented and Revised Introduction to Design Patterns Learned in Java Language
Recommended Posts